global: set an import order rule and reformat with it (#924)
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
parent
4657185dc6
commit
6169920878
62 changed files with 149 additions and 66 deletions
|
@ -17,6 +17,23 @@
|
|||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||
<value />
|
||||
</option>
|
||||
<option name="PACKAGES_IMPORT_LAYOUT">
|
||||
<value>
|
||||
<package name="" alias="false" withSubpackages="true" />
|
||||
<package name="android" alias="false" withSubpackages="true" />
|
||||
<package name="androidx" alias="false" withSubpackages="true" />
|
||||
<package name="com" alias="false" withSubpackages="true" />
|
||||
<package name="java" alias="false" withSubpackages="true" />
|
||||
<package name="javax" alias="false" withSubpackages="true" />
|
||||
<package name="kotlin" alias="false" withSubpackages="true" />
|
||||
<package name="kotlinx" alias="false" withSubpackages="true" />
|
||||
<package name="me" alias="false" withSubpackages="true" />
|
||||
<package name="mozilla" alias="false" withSubpackages="true" />
|
||||
<package name="net" alias="false" withSubpackages="true" />
|
||||
<package name="org" alias="false" withSubpackages="true" />
|
||||
<package name="" alias="true" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
|
||||
<option name="CONTINUATION_INDENT_IN_PARAMETER_LISTS" value="true" />
|
||||
|
|
|
@ -153,6 +153,7 @@ class ClipboardService : Service() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val ACTION_CLEAR = "ACTION_CLEAR_CLIPBOARD"
|
||||
const val ACTION_START = "ACTION_START_CLIPBOARD_TIMER"
|
||||
private const val CHANNEL_ID = "NotificationService"
|
||||
|
|
|
@ -55,6 +55,7 @@ class LaunchActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val ACTION_DECRYPT_PASS = "DECRYPT_PASS"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,10 +35,11 @@ import com.zeapo.pwdstore.utils.PasswordItem
|
|||
import com.zeapo.pwdstore.utils.PasswordRepository
|
||||
import com.zeapo.pwdstore.utils.PreferenceKeys
|
||||
import com.zeapo.pwdstore.utils.viewBinding
|
||||
import me.zhanghai.android.fastscroll.FastScrollerBuilder
|
||||
import java.io.File
|
||||
import me.zhanghai.android.fastscroll.FastScrollerBuilder
|
||||
|
||||
class PasswordFragment : Fragment(R.layout.password_recycler_view) {
|
||||
|
||||
private lateinit var recyclerAdapter: PasswordItemRecyclerAdapter
|
||||
private lateinit var listener: OnFragmentInteractionListener
|
||||
private lateinit var settings: SharedPreferences
|
||||
|
@ -280,6 +281,7 @@ class PasswordFragment : Fragment(R.layout.password_recycler_view) {
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val ITEM_CREATION_REQUEST_KEY = "creation_key"
|
||||
const val ACTION_KEY = "action"
|
||||
const val ACTION_FOLDER = "folder"
|
||||
|
@ -301,6 +303,7 @@ class PasswordFragment : Fragment(R.layout.password_recycler_view) {
|
|||
}
|
||||
|
||||
interface OnFragmentInteractionListener {
|
||||
|
||||
fun onFragmentInteraction(item: PasswordItem)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,14 +70,14 @@ import com.zeapo.pwdstore.utils.contains
|
|||
import com.zeapo.pwdstore.utils.isInsideRepository
|
||||
import com.zeapo.pwdstore.utils.listFilesRecursively
|
||||
import com.zeapo.pwdstore.utils.requestInputFocusOnView
|
||||
import java.io.File
|
||||
import java.lang.Character.UnicodeBlock
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.api.errors.GitAPIException
|
||||
import org.eclipse.jgit.revwalk.RevCommit
|
||||
import java.io.File
|
||||
import java.lang.Character.UnicodeBlock
|
||||
|
||||
class PasswordStore : AppCompatActivity(R.layout.activity_pwdstore) {
|
||||
|
||||
|
@ -904,6 +904,7 @@ class PasswordStore : AppCompatActivity(R.layout.activity_pwdstore) {
|
|||
get() = getSortOrder(settings)
|
||||
|
||||
companion object {
|
||||
|
||||
const val REQUEST_ARG_PATH = "PATH"
|
||||
const val CLONE_REPO_BUTTON = 401
|
||||
const val NEW_REPO_BUTTON = 402
|
||||
|
|
|
@ -31,6 +31,10 @@ import com.zeapo.pwdstore.autofill.oreo.DirectoryStructure
|
|||
import com.zeapo.pwdstore.utils.PasswordItem
|
||||
import com.zeapo.pwdstore.utils.PasswordRepository
|
||||
import com.zeapo.pwdstore.utils.PreferenceKeys
|
||||
import java.io.File
|
||||
import java.text.Collator
|
||||
import java.util.Locale
|
||||
import java.util.Stack
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
|
@ -45,10 +49,6 @@ import kotlinx.coroutines.flow.mapLatest
|
|||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.yield
|
||||
import me.zhanghai.android.fastscroll.PopupTextProvider
|
||||
import java.io.File
|
||||
import java.text.Collator
|
||||
import java.util.Locale
|
||||
import java.util.Stack
|
||||
|
||||
private fun File.toPasswordItem(root: File) = if (isFile)
|
||||
PasswordItem.newPassword(name, this, root)
|
||||
|
@ -380,6 +380,7 @@ class SearchableRepositoryViewModel(application: Application) : AndroidViewModel
|
|||
}
|
||||
|
||||
private object PasswordItemDiffCallback : DiffUtil.ItemCallback<PasswordItem>() {
|
||||
|
||||
override fun areItemsTheSame(oldItem: PasswordItem, newItem: PasswordItem) =
|
||||
oldItem.file.absolutePath == newItem.file.absolutePath
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import com.zeapo.pwdstore.utils.PasswordRepository
|
|||
|
||||
|
||||
class SelectFolderActivity : AppCompatActivity(R.layout.select_folder_layout) {
|
||||
|
||||
private lateinit var passwordList: SelectFolderFragment
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
|
|
@ -16,10 +16,11 @@ import com.zeapo.pwdstore.databinding.PasswordRecyclerViewBinding
|
|||
import com.zeapo.pwdstore.ui.adapters.PasswordItemRecyclerAdapter
|
||||
import com.zeapo.pwdstore.utils.PasswordItem
|
||||
import com.zeapo.pwdstore.utils.viewBinding
|
||||
import me.zhanghai.android.fastscroll.FastScrollerBuilder
|
||||
import java.io.File
|
||||
import me.zhanghai.android.fastscroll.FastScrollerBuilder
|
||||
|
||||
class SelectFolderFragment : Fragment(R.layout.password_recycler_view) {
|
||||
|
||||
private val binding by viewBinding(PasswordRecyclerViewBinding::bind)
|
||||
private lateinit var recyclerAdapter: PasswordItemRecyclerAdapter
|
||||
private lateinit var listener: OnFragmentInteractionListener
|
||||
|
@ -70,6 +71,7 @@ class SelectFolderFragment : Fragment(R.layout.password_recycler_view) {
|
|||
get() = model.currentDir.value!!
|
||||
|
||||
interface OnFragmentInteractionListener {
|
||||
|
||||
fun onFragmentInteraction(item: PasswordItem)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,6 @@ import com.zeapo.pwdstore.utils.PasswordRepository
|
|||
import com.zeapo.pwdstore.utils.PreferenceKeys
|
||||
import com.zeapo.pwdstore.utils.autofillManager
|
||||
import com.zeapo.pwdstore.utils.getEncryptedPrefs
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpUtils
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.time.LocalDateTime
|
||||
|
@ -65,6 +64,7 @@ import java.time.format.DateTimeFormatter
|
|||
import java.util.Calendar
|
||||
import java.util.HashSet
|
||||
import java.util.TimeZone
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpUtils
|
||||
|
||||
typealias ClickListener = Preference.OnPreferenceClickListener
|
||||
typealias ChangeListener = Preference.OnPreferenceChangeListener
|
||||
|
@ -74,6 +74,7 @@ class UserPreference : AppCompatActivity() {
|
|||
private lateinit var prefsFragment: PrefsFragment
|
||||
|
||||
class PrefsFragment : PreferenceFragmentCompat() {
|
||||
|
||||
private var autoFillEnablePreference: SwitchPreferenceCompat? = null
|
||||
private var oreoAutofillChromeCompatFix: SwitchPreferenceCompat? = null
|
||||
private var clearSavedPassPreference: Preference? = null
|
||||
|
@ -843,6 +844,7 @@ class UserPreference : AppCompatActivity() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val TAG = "UserPreference"
|
||||
|
||||
/**
|
||||
|
|
|
@ -90,6 +90,7 @@ class AutofillActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val REQUEST_CODE_DECRYPT_AND_VERIFY = 9913
|
||||
const val REQUEST_CODE_PICK = 777
|
||||
const val REQUEST_CODE_PICK_MATCH_WITH = 778
|
||||
|
|
|
@ -34,6 +34,7 @@ import com.zeapo.pwdstore.utils.resolveAttribute
|
|||
import com.zeapo.pwdstore.utils.splitLines
|
||||
|
||||
class AutofillFragment : DialogFragment() {
|
||||
|
||||
private var adapter: ArrayAdapter<String>? = null
|
||||
private var isWeb: Boolean = false
|
||||
|
||||
|
@ -225,6 +226,7 @@ class AutofillFragment : DialogFragment() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val MATCH_WITH = 777
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,9 +22,9 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton
|
|||
import com.zeapo.pwdstore.R
|
||||
import com.zeapo.pwdstore.databinding.AutofillRecyclerViewBinding
|
||||
import com.zeapo.pwdstore.utils.viewBinding
|
||||
import me.zhanghai.android.fastscroll.FastScrollerBuilder
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.ArrayList
|
||||
import me.zhanghai.android.fastscroll.FastScrollerBuilder
|
||||
|
||||
class AutofillPreferenceActivity : AppCompatActivity() {
|
||||
|
||||
|
|
|
@ -20,9 +20,9 @@ import androidx.recyclerview.widget.SortedList
|
|||
import androidx.recyclerview.widget.SortedListAdapterCallback
|
||||
import com.zeapo.pwdstore.R
|
||||
import com.zeapo.pwdstore.utils.splitLines
|
||||
import me.zhanghai.android.fastscroll.PopupTextProvider
|
||||
import java.util.ArrayList
|
||||
import java.util.Locale
|
||||
import me.zhanghai.android.fastscroll.PopupTextProvider
|
||||
|
||||
internal class AutofillRecyclerAdapter(
|
||||
allApps: List<AppInfo>,
|
||||
|
@ -161,6 +161,7 @@ internal class AutofillRecyclerAdapter(
|
|||
}
|
||||
|
||||
internal inner class ViewHolder(var view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {
|
||||
|
||||
var name: AppCompatTextView = view.findViewById(R.id.app_name)
|
||||
var icon: AppCompatImageView = view.findViewById(R.id.app_icon)
|
||||
var secondary: AppCompatTextView = view.findViewById(R.id.secondary_text)
|
||||
|
|
|
@ -35,15 +35,6 @@ import com.zeapo.pwdstore.model.PasswordEntry
|
|||
import com.zeapo.pwdstore.utils.PasswordRepository
|
||||
import com.zeapo.pwdstore.utils.PreferenceKeys
|
||||
import com.zeapo.pwdstore.utils.splitLines
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpApi
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpServiceConnection
|
||||
import org.openintents.openpgp.IOpenPgpService2
|
||||
import org.openintents.openpgp.OpenPgpError
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
@ -53,8 +44,18 @@ import java.net.MalformedURLException
|
|||
import java.net.URL
|
||||
import java.util.ArrayList
|
||||
import java.util.Locale
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpApi
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpServiceConnection
|
||||
import org.openintents.openpgp.IOpenPgpService2
|
||||
import org.openintents.openpgp.OpenPgpError
|
||||
|
||||
class AutofillService : AccessibilityService(), CoroutineScope by CoroutineScope(Dispatchers.Default) {
|
||||
|
||||
private var serviceConnection: OpenPgpServiceConnection? = null
|
||||
private var settings: SharedPreferences? = null
|
||||
private var info: AccessibilityNodeInfo? = null // the original source of the event (the edittext field)
|
||||
|
@ -560,10 +561,12 @@ class AutofillService : AccessibilityService(), CoroutineScope by CoroutineScope
|
|||
}
|
||||
|
||||
internal object Constants {
|
||||
|
||||
const val TAG = "Keychain"
|
||||
}
|
||||
|
||||
private inner class OnBoundListener : OpenPgpServiceConnection.OnBound {
|
||||
|
||||
override fun onBound(service: IOpenPgpService2) {
|
||||
decryptAndVerify()
|
||||
}
|
||||
|
@ -574,6 +577,7 @@ class AutofillService : AccessibilityService(), CoroutineScope by CoroutineScope
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
var instance: AutofillService? = null
|
||||
private set
|
||||
}
|
||||
|
|
|
@ -89,6 +89,7 @@ val AssistStructure.ViewNode.webOrigin: String?
|
|||
|
||||
data class Credentials(val username: String?, val password: String?, val otp: String?) {
|
||||
companion object {
|
||||
|
||||
fun fromStoreEntry(
|
||||
context: Context,
|
||||
file: File,
|
||||
|
|
|
@ -43,6 +43,7 @@ class AutofillPublisherChangedException(val formOrigin: FormOrigin) :
|
|||
class AutofillMatcher {
|
||||
|
||||
companion object {
|
||||
|
||||
private const val MAX_NUM_MATCHES = 10
|
||||
|
||||
private const val PREFERENCE_PREFIX_TOKEN = "token;"
|
||||
|
|
|
@ -110,6 +110,7 @@ enum class DirectoryStructure(val value: String) {
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val PREFERENCE = "oreo_autofill_directory_structure"
|
||||
private val DEFAULT = FileBased
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ enum class AutofillAction {
|
|||
sealed class AutofillScenario<out T : Any> {
|
||||
|
||||
companion object {
|
||||
|
||||
const val BUNDLE_KEY_USERNAME_ID = "usernameId"
|
||||
const val BUNDLE_KEY_FILL_USERNAME = "fillUsername"
|
||||
const val BUNDLE_KEY_OTP_ID = "otpId"
|
||||
|
@ -64,6 +65,7 @@ sealed class AutofillScenario<out T : Any> {
|
|||
}
|
||||
|
||||
class Builder<T : Any> {
|
||||
|
||||
var username: T? = null
|
||||
var fillUsername = false
|
||||
var otp: T? = null
|
||||
|
|
|
@ -174,6 +174,7 @@ class AutofillRule private constructor(
|
|||
) {
|
||||
|
||||
companion object {
|
||||
|
||||
private var ruleId = 1
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ sealed class FormOrigin(open val identifier: String) {
|
|||
data class App(override val identifier: String) : FormOrigin(identifier)
|
||||
|
||||
companion object {
|
||||
|
||||
private const val BUNDLE_KEY_WEB_IDENTIFIER = "webIdentifier"
|
||||
private const val BUNDLE_KEY_APP_IDENTIFIER = "appIdentifier"
|
||||
|
||||
|
@ -74,6 +75,7 @@ sealed class FormOrigin(open val identifier: String) {
|
|||
private class Form(context: Context, structure: AssistStructure, isManualRequest: Boolean) {
|
||||
|
||||
companion object {
|
||||
|
||||
private val SUPPORTED_SCHEMES = listOf("http", "https")
|
||||
}
|
||||
|
||||
|
@ -202,6 +204,7 @@ class FillableForm private constructor(
|
|||
) {
|
||||
|
||||
companion object {
|
||||
|
||||
fun makeFillInDataset(
|
||||
context: Context,
|
||||
credentials: Credentials,
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.zeapo.pwdstore.utils.hasFlag
|
|||
class OreoAutofillService : AutofillService() {
|
||||
|
||||
companion object {
|
||||
|
||||
// TODO: Provide a user-configurable denylist
|
||||
private val DENYLISTED_PACKAGES = listOf(
|
||||
BuildConfig.APPLICATION_ID,
|
||||
|
|
|
@ -12,6 +12,7 @@ import kotlinx.coroutines.runBlocking
|
|||
import mozilla.components.lib.publicsuffixlist.PublicSuffixList
|
||||
|
||||
private object PublicSuffixListCache {
|
||||
|
||||
private lateinit var publicSuffixList: PublicSuffixList
|
||||
|
||||
fun getOrCachePublicSuffixList(context: Context): PublicSuffixList {
|
||||
|
|
|
@ -24,16 +24,6 @@ import com.zeapo.pwdstore.autofill.oreo.Credentials
|
|||
import com.zeapo.pwdstore.autofill.oreo.DirectoryStructure
|
||||
import com.zeapo.pwdstore.autofill.oreo.FillableForm
|
||||
import com.zeapo.pwdstore.model.PasswordEntry
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpApi
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpServiceConnection
|
||||
import org.openintents.openpgp.IOpenPgpService2
|
||||
import org.openintents.openpgp.OpenPgpError
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
|
@ -44,11 +34,22 @@ import kotlin.coroutines.Continuation
|
|||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.resumeWithException
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpApi
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpServiceConnection
|
||||
import org.openintents.openpgp.IOpenPgpService2
|
||||
import org.openintents.openpgp.OpenPgpError
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
class AutofillDecryptActivity : AppCompatActivity(), CoroutineScope {
|
||||
|
||||
companion object {
|
||||
|
||||
private const val EXTRA_FILE_PATH = "com.zeapo.pwdstore.autofill.oreo.EXTRA_FILE_PATH"
|
||||
private const val EXTRA_SEARCH_ACTION =
|
||||
"com.zeapo.pwdstore.autofill.oreo.EXTRA_SEARCH_ACTION"
|
||||
|
|
|
@ -43,6 +43,7 @@ import com.zeapo.pwdstore.utils.viewBinding
|
|||
class AutofillFilterView : AppCompatActivity() {
|
||||
|
||||
companion object {
|
||||
|
||||
private const val HEIGHT_PERCENTAGE = 0.9
|
||||
private const val WIDTH_PERCENTAGE = 0.75
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import com.zeapo.pwdstore.utils.viewBinding
|
|||
class AutofillPublisherChangedActivity : AppCompatActivity() {
|
||||
|
||||
companion object {
|
||||
|
||||
private const val EXTRA_APP_PACKAGE =
|
||||
"com.zeapo.pwdstore.autofill.oreo.ui.EXTRA_APP_PACKAGE"
|
||||
private var publisherChangedRequestCode = 1
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.io.File
|
|||
class AutofillSaveActivity : AppCompatActivity() {
|
||||
|
||||
companion object {
|
||||
|
||||
private const val EXTRA_FOLDER_NAME =
|
||||
"com.zeapo.pwdstore.autofill.oreo.ui.EXTRA_FOLDER_NAME"
|
||||
private const val EXTRA_PASSWORD = "com.zeapo.pwdstore.autofill.oreo.ui.EXTRA_PASSWORD"
|
||||
|
|
|
@ -10,6 +10,7 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import com.zeapo.pwdstore.R
|
||||
|
||||
class PasswordViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
val title: TextView = itemView.findViewById(R.id.title)
|
||||
val subtitle: TextView = itemView.findViewById(R.id.subtitle)
|
||||
}
|
||||
|
|
|
@ -30,11 +30,11 @@ import com.zeapo.pwdstore.UserPreference
|
|||
import com.zeapo.pwdstore.utils.PreferenceKeys
|
||||
import com.zeapo.pwdstore.utils.clipboard
|
||||
import com.zeapo.pwdstore.utils.snackbar
|
||||
import java.io.File
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpApi
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpServiceConnection
|
||||
import org.openintents.openpgp.IOpenPgpService2
|
||||
import org.openintents.openpgp.OpenPgpError
|
||||
import java.io.File
|
||||
|
||||
@Suppress("Registered")
|
||||
open class BasePgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
|
||||
|
@ -237,6 +237,7 @@ open class BasePgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBou
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val TAG = "APS/BasePgpActivity"
|
||||
const val KEY_PWGEN_TYPE_CLASSIC = "classic"
|
||||
const val KEY_PWGEN_TYPE_XKPASSWD = "xkpasswd"
|
||||
|
|
|
@ -22,6 +22,10 @@ import com.zeapo.pwdstore.databinding.DecryptLayoutBinding
|
|||
import com.zeapo.pwdstore.model.PasswordEntry
|
||||
import com.zeapo.pwdstore.utils.PreferenceKeys
|
||||
import com.zeapo.pwdstore.utils.viewBinding
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import kotlin.time.ExperimentalTime
|
||||
import kotlin.time.seconds
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -29,12 +33,9 @@ import kotlinx.coroutines.withContext
|
|||
import me.msfjarvis.openpgpktx.util.OpenPgpApi
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpServiceConnection
|
||||
import org.openintents.openpgp.IOpenPgpService2
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import kotlin.time.ExperimentalTime
|
||||
import kotlin.time.seconds
|
||||
|
||||
class DecryptActivity : BasePgpActivity(), OpenPgpServiceConnection.OnBound {
|
||||
|
||||
private val binding by viewBinding(DecryptLayoutBinding::inflate)
|
||||
|
||||
private val relativeParentPath by lazy { getParentPath(fullPath, repoPath) }
|
||||
|
|
|
@ -32,15 +32,15 @@ import com.zeapo.pwdstore.utils.commitChange
|
|||
import com.zeapo.pwdstore.utils.isInsideRepository
|
||||
import com.zeapo.pwdstore.utils.snackbar
|
||||
import com.zeapo.pwdstore.utils.viewBinding
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpApi
|
||||
import me.msfjarvis.openpgpktx.util.OpenPgpServiceConnection
|
||||
import org.eclipse.jgit.api.Git
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
class PasswordCreationActivity : BasePgpActivity(), OpenPgpServiceConnection.OnBound {
|
||||
|
||||
|
@ -349,6 +349,7 @@ class PasswordCreationActivity : BasePgpActivity(), OpenPgpServiceConnection.OnB
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val KEY_PWGEN_TYPE_CLASSIC = "classic"
|
||||
private const val KEY_PWGEN_TYPE_XKPASSWD = "xkpasswd"
|
||||
const val RETURN_EXTRA_CREATED_FILE = "CREATED_FILE"
|
||||
|
|
|
@ -243,6 +243,7 @@ abstract class BaseGitActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val REQUEST_ARG_OP = "OPERATION"
|
||||
const val REQUEST_PULL = 101
|
||||
const val REQUEST_PUSH = 102
|
||||
|
|
|
@ -7,13 +7,14 @@ package com.zeapo.pwdstore.git
|
|||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.zeapo.pwdstore.R
|
||||
import java.io.File
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.api.GitCommand
|
||||
import org.eclipse.jgit.api.PushCommand
|
||||
import org.eclipse.jgit.api.RebaseCommand
|
||||
import java.io.File
|
||||
|
||||
class BreakOutOfDetached(fileDir: File, callingActivity: AppCompatActivity) : GitOperation(fileDir, callingActivity) {
|
||||
|
||||
private lateinit var commands: List<GitCommand<out Any>>
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,9 +8,9 @@ import android.content.Intent
|
|||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.zeapo.pwdstore.R
|
||||
import java.io.File
|
||||
import org.eclipse.jgit.api.CloneCommand
|
||||
import org.eclipse.jgit.api.Git
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Creates a new clone operation
|
||||
|
|
|
@ -12,6 +12,8 @@ import androidx.appcompat.app.AppCompatActivity
|
|||
import com.github.ajalt.timberkt.e
|
||||
import com.zeapo.pwdstore.R
|
||||
import com.zeapo.pwdstore.git.config.SshjSessionFactory
|
||||
import java.io.IOException
|
||||
import java.lang.ref.WeakReference
|
||||
import net.schmizz.sshj.common.DisconnectReason
|
||||
import net.schmizz.sshj.common.SSHException
|
||||
import net.schmizz.sshj.userauth.UserAuthException
|
||||
|
@ -23,8 +25,6 @@ import org.eclipse.jgit.api.RebaseResult
|
|||
import org.eclipse.jgit.api.StatusCommand
|
||||
import org.eclipse.jgit.transport.RemoteRefUpdate
|
||||
import org.eclipse.jgit.transport.SshSessionFactory
|
||||
import java.io.IOException
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
|
||||
class GitAsyncTask(
|
||||
|
|
|
@ -26,6 +26,9 @@ import com.zeapo.pwdstore.utils.PasswordRepository
|
|||
import com.zeapo.pwdstore.utils.PreferenceKeys
|
||||
import com.zeapo.pwdstore.utils.getEncryptedPrefs
|
||||
import com.zeapo.pwdstore.utils.requestInputFocusOnView
|
||||
import java.io.File
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.resume
|
||||
import net.schmizz.sshj.userauth.password.PasswordFinder
|
||||
import org.eclipse.jgit.api.GitCommand
|
||||
import org.eclipse.jgit.errors.UnsupportedCredentialItem
|
||||
|
@ -34,9 +37,6 @@ import org.eclipse.jgit.transport.CredentialItem
|
|||
import org.eclipse.jgit.transport.CredentialsProvider
|
||||
import org.eclipse.jgit.transport.SshSessionFactory
|
||||
import org.eclipse.jgit.transport.URIish
|
||||
import java.io.File
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.resume
|
||||
import com.google.android.material.R as materialR
|
||||
|
||||
|
||||
|
@ -245,6 +245,7 @@ abstract class GitOperation(gitDir: File, internal val callingActivity: AppCompa
|
|||
open fun onSuccess() {}
|
||||
|
||||
companion object {
|
||||
|
||||
const val GET_SSH_KEY_FROM_CLONE = 201
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import com.zeapo.pwdstore.UserPreference
|
|||
import com.zeapo.pwdstore.utils.PasswordRepository
|
||||
|
||||
open class GitOperationActivity : BaseGitActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
when (intent.extras?.getInt(REQUEST_ARG_OP)) {
|
||||
|
|
|
@ -8,9 +8,9 @@ import android.content.Intent
|
|||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.zeapo.pwdstore.R
|
||||
import java.io.File
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.api.PullCommand
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Creates a new git operation
|
||||
|
|
|
@ -8,9 +8,9 @@ import android.content.Intent
|
|||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.zeapo.pwdstore.R
|
||||
import java.io.File
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.api.PushCommand
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Creates a new git operation
|
||||
|
|
|
@ -8,11 +8,11 @@ import android.content.Intent
|
|||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.zeapo.pwdstore.R
|
||||
import java.io.File
|
||||
import org.eclipse.jgit.api.AddCommand
|
||||
import org.eclipse.jgit.api.FetchCommand
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.api.ResetCommand
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Creates a new git operation
|
||||
|
|
|
@ -8,13 +8,13 @@ import android.content.Intent
|
|||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.zeapo.pwdstore.R
|
||||
import java.io.File
|
||||
import org.eclipse.jgit.api.AddCommand
|
||||
import org.eclipse.jgit.api.CommitCommand
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.api.PullCommand
|
||||
import org.eclipse.jgit.api.PushCommand
|
||||
import org.eclipse.jgit.api.StatusCommand
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Creates a new git operation
|
||||
|
|
|
@ -12,6 +12,7 @@ enum class ConnectionMode(val pref: String) {
|
|||
;
|
||||
|
||||
companion object {
|
||||
|
||||
private val map = values().associateBy(ConnectionMode::pref)
|
||||
fun fromString(type: String?): ConnectionMode {
|
||||
return map[type ?: return SshKey]
|
||||
|
|
|
@ -10,6 +10,7 @@ enum class Protocol(val pref: String) {
|
|||
;
|
||||
|
||||
companion object {
|
||||
|
||||
private val map = values().associateBy(Protocol::pref)
|
||||
fun fromString(type: String?): Protocol {
|
||||
return map[type ?: return Ssh]
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.hierynomus.sshj.signature.SignatureEdDSA
|
|||
import com.hierynomus.sshj.transport.cipher.BlockCiphers
|
||||
import com.hierynomus.sshj.transport.mac.Macs
|
||||
import com.hierynomus.sshj.userauth.keyprovider.OpenSSHKeyV1KeyFile
|
||||
import java.security.Security
|
||||
import net.schmizz.keepalive.KeepAliveProvider
|
||||
import net.schmizz.sshj.ConfigImpl
|
||||
import net.schmizz.sshj.common.LoggerFactory
|
||||
|
@ -30,7 +31,6 @@ import net.schmizz.sshj.userauth.keyprovider.PuTTYKeyFile
|
|||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.Marker
|
||||
import java.security.Security
|
||||
|
||||
|
||||
fun setUpBouncyCastleForSshj() {
|
||||
|
|
|
@ -8,6 +8,14 @@ import android.util.Base64
|
|||
import com.github.ajalt.timberkt.d
|
||||
import com.github.ajalt.timberkt.w
|
||||
import com.zeapo.pwdstore.utils.clear
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.security.GeneralSecurityException
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.schmizz.sshj.SSHClient
|
||||
|
@ -26,23 +34,17 @@ import org.eclipse.jgit.transport.RemoteSession
|
|||
import org.eclipse.jgit.transport.SshSessionFactory
|
||||
import org.eclipse.jgit.transport.URIish
|
||||
import org.eclipse.jgit.util.FS
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.security.GeneralSecurityException
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
sealed class SshAuthData {
|
||||
class Password(val passwordFinder: InteractivePasswordFinder) : SshAuthData() {
|
||||
|
||||
override fun clearCredentials() {
|
||||
passwordFinder.clearPasswords()
|
||||
}
|
||||
}
|
||||
|
||||
class PublicKeyFile(val keyFile: File, val passphraseFinder: InteractivePasswordFinder) : SshAuthData() {
|
||||
|
||||
override fun clearCredentials() {
|
||||
passphraseFinder.clearPasswords()
|
||||
}
|
||||
|
|
|
@ -106,6 +106,7 @@ class PasswordEntry(content: String, private val totpFinder: TotpFinder = UriTot
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
val USERNAME_FIELDS = arrayOf(
|
||||
"login:",
|
||||
"username:",
|
||||
|
|
|
@ -21,6 +21,7 @@ enum class PasswordOption(val key: String) {
|
|||
}
|
||||
|
||||
object PasswordGenerator {
|
||||
|
||||
const val DEFAULT_LENGTH = 16
|
||||
|
||||
const val DIGITS = 0x0001
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.zeapo.pwdstore.utils.hasFlag
|
|||
import java.util.Locale
|
||||
|
||||
object RandomPhonemesGenerator {
|
||||
|
||||
private const val CONSONANT = 0x0001
|
||||
private const val VOWEL = 0x0002
|
||||
private const val DIPHTHONG = 0x0004
|
||||
|
@ -57,6 +58,7 @@ object RandomPhonemesGenerator {
|
|||
)
|
||||
|
||||
private class Element(str: String, val flags: Int) {
|
||||
|
||||
val upperCase = str.toUpperCase(Locale.ROOT)
|
||||
val lowerCase = str.toLowerCase(Locale.ROOT)
|
||||
val length = str.length
|
||||
|
|
|
@ -138,6 +138,7 @@ class PasswordBuilder(ctx: Context) {
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val SYMBOLS = "!@\$%^&*-_+=:|~?/.;#"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.zeapo.pwdstore.utils.PreferenceKeys
|
|||
import java.io.File
|
||||
|
||||
class XkpwdDictionary(context: Context) {
|
||||
|
||||
val words: Map<Int, List<String>>
|
||||
|
||||
init {
|
||||
|
@ -32,6 +33,7 @@ class XkpwdDictionary(context: Context) {
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val XKPWD_CUSTOM_DICT_FILE = "custom_dict.txt"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,11 +20,11 @@ import com.zeapo.pwdstore.R
|
|||
import com.zeapo.pwdstore.databinding.ActivitySshKeygenBinding
|
||||
import com.zeapo.pwdstore.utils.getEncryptedPrefs
|
||||
import com.zeapo.pwdstore.utils.viewBinding
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
|
||||
class SshKeyGenActivity : AppCompatActivity() {
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ open class PasswordItemRecyclerAdapter :
|
|||
}
|
||||
|
||||
class PasswordItemViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
private val name: AppCompatTextView = itemView.findViewById(R.id.label)
|
||||
private val typeImage: AppCompatImageView = itemView.findViewById(R.id.type_image)
|
||||
private val childCount: AppCompatTextView = itemView.findViewById(R.id.child_count)
|
||||
|
|
|
@ -43,6 +43,7 @@ class FolderCreationDialogFragment : DialogFragment() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val CURRENT_DIR_EXTRA = "CURRENT_DIRECTORY"
|
||||
fun newInstance(startingDirectory: String): FolderCreationDialogFragment {
|
||||
val extras = bundleOf(CURRENT_DIR_EXTRA to startingDirectory)
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.zeapo.pwdstore.R
|
|||
import com.zeapo.pwdstore.utils.resolveAttribute
|
||||
|
||||
class ItemCreationBottomSheet : BottomSheetDialogFragment() {
|
||||
|
||||
private var behavior: BottomSheetBehavior<FrameLayout>? = null
|
||||
private val bottomSheetCallback = object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onSlide(bottomSheet: View, slideOffset: Float) {
|
||||
|
|
|
@ -109,6 +109,7 @@ class XkPasswordGeneratorDialogFragment : DialogFragment() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val PREF_KEY_CAPITALS_STYLE = "pref_key_capitals_style"
|
||||
const val PREF_KEY_NUM_WORDS = "pref_key_num_words"
|
||||
const val PREF_KEY_SEPARATOR = "pref_key_separator"
|
||||
|
|
|
@ -17,6 +17,7 @@ import com.github.ajalt.timberkt.d
|
|||
import com.zeapo.pwdstore.R
|
||||
|
||||
object BiometricAuthenticator {
|
||||
|
||||
private const val TAG = "BiometricAuthenticator"
|
||||
private val handler = Handler()
|
||||
|
||||
|
|
|
@ -26,8 +26,8 @@ import com.google.android.material.snackbar.Snackbar
|
|||
import com.zeapo.pwdstore.git.GitAsyncTask
|
||||
import com.zeapo.pwdstore.git.GitOperation
|
||||
import com.zeapo.pwdstore.utils.PasswordRepository.Companion.getRepositoryDirectory
|
||||
import org.eclipse.jgit.api.Git
|
||||
import java.io.File
|
||||
import org.eclipse.jgit.api.Git
|
||||
|
||||
fun Int.clearFlag(flag: Int): Int {
|
||||
return this and flag.inv()
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
package com.zeapo.pwdstore.utils
|
||||
|
||||
import com.github.ajalt.timberkt.e
|
||||
import org.apache.commons.codec.binary.Base32
|
||||
import java.nio.ByteBuffer
|
||||
import java.security.InvalidKeyException
|
||||
import java.security.NoSuchAlgorithmException
|
||||
|
@ -14,8 +13,10 @@ import java.util.Locale
|
|||
import javax.crypto.Mac
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
import kotlin.experimental.and
|
||||
import org.apache.commons.codec.binary.Base32
|
||||
|
||||
object Otp {
|
||||
|
||||
private val BASE_32 = Base32()
|
||||
private val STEAM_ALPHABET = "23456789BCDFGHJKMNPQRTVWXY".toCharArray()
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ data class PasswordItem(
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val TYPE_CATEGORY = 'c'
|
||||
const val TYPE_PASSWORD = 'p'
|
||||
|
||||
|
|
|
@ -8,15 +8,15 @@ import android.content.Context
|
|||
import android.content.SharedPreferences
|
||||
import androidx.core.content.edit
|
||||
import androidx.preference.PreferenceManager
|
||||
import java.io.File
|
||||
import java.io.FileFilter
|
||||
import java.util.Comparator
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.lib.Repository
|
||||
import org.eclipse.jgit.storage.file.FileRepositoryBuilder
|
||||
import org.eclipse.jgit.transport.RefSpec
|
||||
import org.eclipse.jgit.transport.RemoteConfig
|
||||
import org.eclipse.jgit.transport.URIish
|
||||
import java.io.File
|
||||
import java.io.FileFilter
|
||||
import java.util.Comparator
|
||||
|
||||
open class PasswordRepository protected constructor() {
|
||||
|
||||
|
@ -37,6 +37,7 @@ open class PasswordRepository protected constructor() {
|
|||
});
|
||||
|
||||
companion object {
|
||||
|
||||
@JvmStatic
|
||||
fun getSortOrder(settings: SharedPreferences): PasswordSortOrder {
|
||||
return valueOf(settings.getString(PreferenceKeys.SORT_ORDER, null)
|
||||
|
|
|
@ -31,6 +31,7 @@ class PublicSuffixList(
|
|||
dispatcher: CoroutineDispatcher = Dispatchers.IO,
|
||||
private val scope: CoroutineScope = CoroutineScope(dispatcher)
|
||||
) {
|
||||
|
||||
private val data: PublicSuffixListData by lazy { PublicSuffixListLoader.load(context) }
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,6 +17,7 @@ internal class PublicSuffixListData(
|
|||
private val rules: ByteArray,
|
||||
private val exceptions: ByteArray
|
||||
) {
|
||||
|
||||
private fun binarySearchRules(labels: List<ByteArray>, labelIndex: Int): String? {
|
||||
return rules.binarySearch(labels, labelIndex)
|
||||
}
|
||||
|
@ -147,6 +148,7 @@ internal class PublicSuffixListData(
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
val WILDCARD_LABEL = byteArrayOf('*'.toByte())
|
||||
val PREVAILING_RULE = listOf("*")
|
||||
val EMPTY_RULE = listOf<String>()
|
||||
|
|
|
@ -14,6 +14,7 @@ import java.io.IOException
|
|||
private const val PUBLIC_SUFFIX_LIST_FILE = "publicsuffixes"
|
||||
|
||||
internal object PublicSuffixListLoader {
|
||||
|
||||
fun load(context: Context): PublicSuffixListData = context.assets.open(
|
||||
PUBLIC_SUFFIX_LIST_FILE
|
||||
).buffered().use { stream ->
|
||||
|
|
Loading…
Reference in a new issue