mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Merge branch 'release/4.2.2'
This commit is contained in:
@@ -1,3 +1,9 @@
|
|||||||
|
KeePassDX(4.2.2)
|
||||||
|
* Fix database merge algorithm #2223
|
||||||
|
* Fix save search info #2243
|
||||||
|
* Fix Play Service as privileged app for Passkey Cross Device Authentication #2244
|
||||||
|
* Small fixes
|
||||||
|
|
||||||
KeePassDX(4.2.1)
|
KeePassDX(4.2.1)
|
||||||
* Fix Magikeyboard autosearch #2233
|
* Fix Magikeyboard autosearch #2233
|
||||||
* Fix database merge #2223
|
* Fix database merge #2223
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ android {
|
|||||||
applicationId "com.kunzisoft.keepass"
|
applicationId "com.kunzisoft.keepass"
|
||||||
minSdkVersion 19
|
minSdkVersion 19
|
||||||
targetSdkVersion 35
|
targetSdkVersion 35
|
||||||
versionCode = 146
|
versionCode = 147
|
||||||
versionName = "4.2.1"
|
versionName = "4.2.2"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
|
|
||||||
testApplicationId = "com.kunzisoft.keepass.tests"
|
testApplicationId = "com.kunzisoft.keepass.tests"
|
||||||
|
|||||||
@@ -125,6 +125,8 @@ class EntryActivity : DatabaseLockActivity() {
|
|||||||
private var mBackgroundColor: Int? = null
|
private var mBackgroundColor: Int? = null
|
||||||
private var mForegroundColor: Int? = null
|
private var mForegroundColor: Int? = null
|
||||||
|
|
||||||
|
override fun manageDatabaseInfo(): Boolean = true
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
|||||||
@@ -157,6 +157,8 @@ class EntryEditActivity : DatabaseLockActivity(),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun manageDatabaseInfo(): Boolean = true
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_entry_edit)
|
setContentView(R.layout.activity_entry_edit)
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
|
|||||||
|
|
||||||
private var mExternalFileHelper: ExternalFileHelper? = null
|
private var mExternalFileHelper: ExternalFileHelper? = null
|
||||||
|
|
||||||
|
override fun manageDatabaseInfo(): Boolean = false
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
@@ -250,13 +252,13 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
|
|||||||
database,
|
database,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
coordinatorLayout.showActionErrorIfNeeded(result)
|
||||||
}
|
}
|
||||||
ACTION_DATABASE_LOAD_TASK -> {
|
ACTION_DATABASE_LOAD_TASK -> {
|
||||||
launchGroupActivityIfLoaded(database)
|
launchGroupActivityIfLoaded(database)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
coordinatorLayout.showActionErrorIfNeeded(result)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -274,6 +274,8 @@ class GroupActivity : DatabaseLockActivity(),
|
|||||||
mGroupEditViewModel.selectIcon(icon)
|
mGroupEditViewModel.selectIcon(icon)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun manageDatabaseInfo(): Boolean = true
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
@@ -871,9 +873,10 @@ class GroupActivity : DatabaseLockActivity(),
|
|||||||
entryVersioned,
|
entryVersioned,
|
||||||
searchInfo.toRegisterInfo()
|
searchInfo.toRegisterInfo()
|
||||||
)
|
)
|
||||||
}
|
} else {
|
||||||
entrySelectedForKeyboardSelection(database, entryVersioned)
|
entrySelectedForKeyboardSelection(database, entryVersioned)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
TypeMode.PASSKEY -> {
|
TypeMode.PASSKEY -> {
|
||||||
entrySelectedForPasskeySelection(database, entryVersioned)
|
entrySelectedForPasskeySelection(database, entryVersioned)
|
||||||
}
|
}
|
||||||
@@ -887,10 +890,11 @@ class GroupActivity : DatabaseLockActivity(),
|
|||||||
entryVersioned,
|
entryVersioned,
|
||||||
searchInfo.toRegisterInfo()
|
searchInfo.toRegisterInfo()
|
||||||
)
|
)
|
||||||
}
|
} else {
|
||||||
entrySelectedForAutofillSelection(database, entryVersioned)
|
entrySelectedForAutofillSelection(database, entryVersioned)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
loadGroup()
|
loadGroup()
|
||||||
},
|
},
|
||||||
registrationAction = { intentSenderMode, typeMode, registerInfo ->
|
registrationAction = { intentSenderMode, typeMode, registerInfo ->
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ class IconPickerActivity : DatabaseLockActivity() {
|
|||||||
|
|
||||||
private var mExternalFileHelper: ExternalFileHelper? = null
|
private var mExternalFileHelper: ExternalFileHelper? = null
|
||||||
|
|
||||||
|
override fun manageDatabaseInfo(): Boolean = true
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ class ImageViewerActivity : DatabaseLockActivity() {
|
|||||||
private lateinit var imageView: ImageView
|
private lateinit var imageView: ImageView
|
||||||
private lateinit var progressView: View
|
private lateinit var progressView: View
|
||||||
|
|
||||||
|
override fun manageDatabaseInfo(): Boolean = false
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ class KeyGeneratorActivity : DatabaseLockActivity() {
|
|||||||
private lateinit var validationButton: View
|
private lateinit var validationButton: View
|
||||||
private var lockView: View? = null
|
private var lockView: View? = null
|
||||||
|
|
||||||
|
override fun manageDatabaseInfo(): Boolean = true
|
||||||
|
|
||||||
private val keyGeneratorViewModel: KeyGeneratorViewModel by viewModels()
|
private val keyGeneratorViewModel: KeyGeneratorViewModel by viewModels()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
|||||||
@@ -124,6 +124,8 @@ class MainCredentialActivity : DatabaseModeActivity() {
|
|||||||
private var mReadOnly: Boolean = false
|
private var mReadOnly: Boolean = false
|
||||||
private var mForceReadOnly: Boolean = false
|
private var mForceReadOnly: Boolean = false
|
||||||
|
|
||||||
|
override fun manageDatabaseInfo(): Boolean = false
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ import com.kunzisoft.keepass.activities.dialogs.DatabaseChangedDialogFragment.Co
|
|||||||
import com.kunzisoft.keepass.activities.stylish.StylishActivity
|
import com.kunzisoft.keepass.activities.stylish.StylishActivity
|
||||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||||
import com.kunzisoft.keepass.database.DatabaseTaskProvider.Companion.startDatabaseService
|
import com.kunzisoft.keepass.database.DatabaseTaskProvider.Companion.startDatabaseService
|
||||||
import com.kunzisoft.keepass.database.ProgressMessage
|
|
||||||
import com.kunzisoft.keepass.model.SnapFileDatabaseInfo
|
import com.kunzisoft.keepass.model.SnapFileDatabaseInfo
|
||||||
import com.kunzisoft.keepass.tasks.ActionRunnable
|
import com.kunzisoft.keepass.tasks.ActionRunnable
|
||||||
import com.kunzisoft.keepass.tasks.ProgressTaskDialogFragment
|
import com.kunzisoft.keepass.tasks.ProgressTaskDialogFragment
|
||||||
import com.kunzisoft.keepass.tasks.ProgressTaskDialogFragment.Companion.PROGRESS_TASK_DIALOG_TAG
|
import com.kunzisoft.keepass.tasks.ProgressTaskDialogFragment.Companion.PROGRESS_TASK_DIALOG_TAG
|
||||||
|
import com.kunzisoft.keepass.tasks.ProgressTaskViewModel
|
||||||
import com.kunzisoft.keepass.viewmodels.DatabaseViewModel
|
import com.kunzisoft.keepass.viewmodels.DatabaseViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@@ -32,6 +32,7 @@ abstract class DatabaseActivity : StylishActivity(), DatabaseRetrieval {
|
|||||||
protected val mDatabase: ContextualDatabase?
|
protected val mDatabase: ContextualDatabase?
|
||||||
get() = mDatabaseViewModel.database
|
get() = mDatabaseViewModel.database
|
||||||
|
|
||||||
|
private val progressTaskViewModel: ProgressTaskViewModel by viewModels()
|
||||||
private var progressTaskDialogFragment: ProgressTaskDialogFragment? = null
|
private var progressTaskDialogFragment: ProgressTaskDialogFragment? = null
|
||||||
private var databaseChangedDialogFragment: DatabaseChangedDialogFragment? = null
|
private var databaseChangedDialogFragment: DatabaseChangedDialogFragment? = null
|
||||||
|
|
||||||
@@ -81,13 +82,13 @@ abstract class DatabaseActivity : StylishActivity(), DatabaseRetrieval {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
is DatabaseViewModel.ActionState.OnDatabaseActionStarted -> {
|
is DatabaseViewModel.ActionState.OnDatabaseActionStarted -> {
|
||||||
showDialog(uiState.progressMessage)
|
progressTaskViewModel.start(uiState.progressMessage)
|
||||||
}
|
}
|
||||||
is DatabaseViewModel.ActionState.OnDatabaseActionUpdated -> {
|
is DatabaseViewModel.ActionState.OnDatabaseActionUpdated -> {
|
||||||
showDialog(uiState.progressMessage)
|
progressTaskViewModel.update(uiState.progressMessage)
|
||||||
}
|
}
|
||||||
is DatabaseViewModel.ActionState.OnDatabaseActionStopped -> {
|
is DatabaseViewModel.ActionState.OnDatabaseActionStopped -> {
|
||||||
// nothing here, wait for the action to finish
|
progressTaskViewModel.stop()
|
||||||
}
|
}
|
||||||
is DatabaseViewModel.ActionState.OnDatabaseActionFinished -> {
|
is DatabaseViewModel.ActionState.OnDatabaseActionFinished -> {
|
||||||
onDatabaseActionFinished(
|
onDatabaseActionFinished(
|
||||||
@@ -95,12 +96,24 @@ abstract class DatabaseActivity : StylishActivity(), DatabaseRetrieval {
|
|||||||
uiState.actionTask,
|
uiState.actionTask,
|
||||||
uiState.result
|
uiState.result
|
||||||
)
|
)
|
||||||
stopDialog()
|
progressTaskViewModel.stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||||
|
progressTaskViewModel.progressTaskState.collect { state ->
|
||||||
|
when (state) {
|
||||||
|
ProgressTaskViewModel.ProgressTaskState.Start ->
|
||||||
|
showDialog()
|
||||||
|
ProgressTaskViewModel.ProgressTaskState.Stop ->
|
||||||
|
stopDialog()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||||
mDatabaseViewModel.databaseState.collect { database ->
|
mDatabaseViewModel.databaseState.collect { database ->
|
||||||
@@ -194,7 +207,7 @@ abstract class DatabaseActivity : StylishActivity(), DatabaseRetrieval {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showDialog(progressMessage: ProgressMessage) {
|
private fun showDialog() {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
if (showDatabaseDialog()) {
|
if (showDatabaseDialog()) {
|
||||||
if (progressTaskDialogFragment == null) {
|
if (progressTaskDialogFragment == null) {
|
||||||
@@ -208,12 +221,6 @@ abstract class DatabaseActivity : StylishActivity(), DatabaseRetrieval {
|
|||||||
PROGRESS_TASK_DIALOG_TAG
|
PROGRESS_TASK_DIALOG_TAG
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
progressTaskDialogFragment?.apply {
|
|
||||||
updateTitle(progressMessage.titleId)
|
|
||||||
updateMessage(progressMessage.messageId)
|
|
||||||
updateWarning(progressMessage.warningId)
|
|
||||||
setCancellable(progressMessage.cancelable)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -370,9 +370,11 @@ abstract class DatabaseLockActivity : DatabaseModeActivity(),
|
|||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
.setPositiveButton(R.string.lock) { _, _ ->
|
.setPositiveButton(R.string.lock) { _, _ ->
|
||||||
sendBroadcast(Intent(LOCK_ACTION))
|
sendBroadcast(Intent(LOCK_ACTION))
|
||||||
|
finish()
|
||||||
}.create().show()
|
}.create().show()
|
||||||
} else {
|
} else {
|
||||||
sendBroadcast(Intent(LOCK_ACTION))
|
sendBroadcast(Intent(LOCK_ACTION))
|
||||||
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,13 +70,11 @@ class AutofillLauncherActivity : DatabaseModeActivity() {
|
|||||||
autofillLauncherViewModel.manageRegistrationResult(it)
|
autofillLauncherViewModel.manageRegistrationResult(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyCustomStyle(): Boolean {
|
override fun applyCustomStyle(): Boolean = false
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun finishActivityIfReloadRequested(): Boolean {
|
override fun finishActivityIfReloadRequested(): Boolean = true
|
||||||
return true
|
|
||||||
}
|
override fun manageDatabaseInfo(): Boolean = false
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
// To apply the bypass https://github.com/Kunzisoft/KeePassDX/issues/2238
|
// To apply the bypass https://github.com/Kunzisoft/KeePassDX/issues/2238
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ class EntrySelectionLauncherActivity : DatabaseModeActivity() {
|
|||||||
|
|
||||||
override fun finishActivityIfReloadRequested() = false
|
override fun finishActivityIfReloadRequested() = false
|
||||||
|
|
||||||
|
override fun manageDatabaseInfo(): Boolean = false
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
entrySelectionViewModel.initialize()
|
entrySelectionViewModel.initialize()
|
||||||
|
|||||||
@@ -121,7 +121,6 @@ class DatabaseTaskProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initServiceConnection() {
|
private fun initServiceConnection() {
|
||||||
actionTaskListener?.onActionStopped()
|
|
||||||
if (serviceConnection == null) {
|
if (serviceConnection == null) {
|
||||||
serviceConnection = object : ServiceConnection {
|
serviceConnection = object : ServiceConnection {
|
||||||
override fun onBindingDied(name: ComponentName?) {
|
override fun onBindingDied(name: ComponentName?) {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import androidx.annotation.StringRes
|
|||||||
|
|
||||||
data class ProgressMessage(
|
data class ProgressMessage(
|
||||||
@StringRes
|
@StringRes
|
||||||
var titleId: Int,
|
var titleId: Int? = null,
|
||||||
@StringRes
|
@StringRes
|
||||||
var messageId: Int? = null,
|
var messageId: Int? = null,
|
||||||
@StringRes
|
@StringRes
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ class AttachmentFileNotificationService: LockNotificationService() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (attachmentNotificationList.isEmpty()) {
|
if (attachmentNotificationList.isEmpty()) {
|
||||||
stopSelf()
|
stopService()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class ClipboardEntryNotificationService : LockNotificationService() {
|
|||||||
sendBroadcast(Intent(LOCK_ACTION))
|
sendBroadcast(Intent(LOCK_ACTION))
|
||||||
}
|
}
|
||||||
// Stop the service
|
// Stop the service
|
||||||
stopSelf()
|
stopService()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
|
|||||||
@@ -262,11 +262,12 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
/* Do not stopped here, service cannot be connected
|
||||||
mActionTaskListeners.forEach { actionTaskListener ->
|
mActionTaskListeners.forEach { actionTaskListener ->
|
||||||
actionTaskListener.onActionStopped(
|
actionTaskListener.onActionStopped(
|
||||||
database
|
database
|
||||||
)
|
)
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -338,7 +339,7 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
|||||||
val intentAction = intent?.action
|
val intentAction = intent?.action
|
||||||
|
|
||||||
if (intentAction == null && !database.loaded) {
|
if (intentAction == null && !database.loaded) {
|
||||||
stopSelf()
|
stopService()
|
||||||
}
|
}
|
||||||
|
|
||||||
val actionRunnable: ActionRunnable? = when (intentAction) {
|
val actionRunnable: ActionRunnable? = when (intentAction) {
|
||||||
@@ -447,10 +448,10 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
|||||||
TimeoutHelper.releaseTemporarilyDisableTimeout()
|
TimeoutHelper.releaseTemporarilyDisableTimeout()
|
||||||
// Stop service after save if user remove task
|
// Stop service after save if user remove task
|
||||||
if (save && mTaskRemovedRequested) {
|
if (save && mTaskRemovedRequested) {
|
||||||
actionOnLock()
|
stopService()
|
||||||
} else if (TimeoutHelper.checkTimeAndLockIfTimeout(this@DatabaseTaskNotificationService)) {
|
} else if (TimeoutHelper.checkTimeAndLockIfTimeout(this@DatabaseTaskNotificationService)) {
|
||||||
if (!database.loaded) {
|
if (!database.loaded) {
|
||||||
stopSelf()
|
stopService()
|
||||||
} else {
|
} else {
|
||||||
// Restart the service to open lock notification
|
// Restart the service to open lock notification
|
||||||
try {
|
try {
|
||||||
@@ -535,11 +536,10 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
|||||||
|
|
||||||
val notificationBuilder = buildNewNotification().apply {
|
val notificationBuilder = buildNewNotification().apply {
|
||||||
setSmallIcon(iconId)
|
setSmallIcon(iconId)
|
||||||
intent?.let {
|
val titleId = mProgressMessage.titleId?.let {
|
||||||
setContentTitle(getString(
|
intent?.getIntExtra(DATABASE_TASK_TITLE_KEY, it)
|
||||||
intent.getIntExtra(DATABASE_TASK_TITLE_KEY, mProgressMessage.titleId))
|
} ?: R.string.app_name
|
||||||
)
|
setContentTitle(getString(titleId))
|
||||||
}
|
|
||||||
setAutoCancel(false)
|
setAutoCancel(false)
|
||||||
setContentIntent(null)
|
setContentIntent(null)
|
||||||
}
|
}
|
||||||
@@ -673,7 +673,7 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
|||||||
updateMessage(R.string.decrypting_db)
|
updateMessage(R.string.decrypting_db)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun actionOnLock() {
|
override fun stopService() {
|
||||||
if (!TimeoutHelper.temporarilyDisableLock) {
|
if (!TimeoutHelper.temporarilyDisableLock) {
|
||||||
closeDatabase(mDatabase)
|
closeDatabase(mDatabase)
|
||||||
// Remove the database during the lock
|
// Remove the database during the lock
|
||||||
@@ -685,7 +685,7 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
|||||||
// Remove the lock timer (no more needed if it exists)
|
// Remove the lock timer (no more needed if it exists)
|
||||||
TimeoutHelper.cancelLockTimer(this)
|
TimeoutHelper.cancelLockTimer(this)
|
||||||
// Service is stopped after receive the broadcast
|
// Service is stopped after receive the broadcast
|
||||||
super.actionOnLock()
|
super.stopService()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -729,7 +729,9 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
|||||||
// Close channels
|
// Close channels
|
||||||
closeChallengeResponse()
|
closeChallengeResponse()
|
||||||
// Restore previous message
|
// Restore previous message
|
||||||
mProgressMessage = previousMessage
|
mProgressMessage = previousMessage.apply {
|
||||||
|
cancelable = null
|
||||||
|
}
|
||||||
notifyProgressMessage()
|
notifyProgressMessage()
|
||||||
}
|
}
|
||||||
return response
|
return response
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class KeyboardEntryNotificationService : LockNotificationService() {
|
|||||||
sendBroadcast(Intent(LOCK_ACTION))
|
sendBroadcast(Intent(LOCK_ACTION))
|
||||||
}
|
}
|
||||||
// Stop the service
|
// Stop the service
|
||||||
stopSelf()
|
stopService()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
package com.kunzisoft.keepass.services
|
package com.kunzisoft.keepass.services
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.core.app.ServiceCompat
|
|
||||||
import com.kunzisoft.keepass.timeout.TimeoutHelper
|
import com.kunzisoft.keepass.timeout.TimeoutHelper
|
||||||
import com.kunzisoft.keepass.utils.LockReceiver
|
import com.kunzisoft.keepass.utils.LockReceiver
|
||||||
import com.kunzisoft.keepass.utils.registerLockReceiver
|
import com.kunzisoft.keepass.utils.registerLockReceiver
|
||||||
@@ -29,13 +28,7 @@ import com.kunzisoft.keepass.utils.unregisterLockReceiver
|
|||||||
abstract class LockNotificationService : NotificationService() {
|
abstract class LockNotificationService : NotificationService() {
|
||||||
|
|
||||||
private var mLockReceiver: LockReceiver = LockReceiver {
|
private var mLockReceiver: LockReceiver = LockReceiver {
|
||||||
actionOnLock()
|
stopService()
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun actionOnLock() {
|
|
||||||
// Stop the service in all cases
|
|
||||||
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE)
|
|
||||||
stopSelf()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
@@ -46,7 +39,7 @@ abstract class LockNotificationService : NotificationService() {
|
|||||||
|
|
||||||
override fun onTaskRemoved(rootIntent: Intent?) {
|
override fun onTaskRemoved(rootIntent: Intent?) {
|
||||||
if (!TimeoutHelper.temporarilyDisableLock) {
|
if (!TimeoutHelper.temporarilyDisableLock) {
|
||||||
actionOnLock()
|
stopService()
|
||||||
}
|
}
|
||||||
super.onTaskRemoved(rootIntent)
|
super.onTaskRemoved(rootIntent)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import android.util.TypedValue
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import androidx.core.app.ServiceCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.kunzisoft.keepass.R
|
import com.kunzisoft.keepass.R
|
||||||
import com.kunzisoft.keepass.activities.stylish.Stylish
|
import com.kunzisoft.keepass.activities.stylish.Stylish
|
||||||
@@ -114,6 +115,12 @@ abstract class NotificationService : Service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun stopService() {
|
||||||
|
// Stop the service in all cases
|
||||||
|
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE)
|
||||||
|
stopSelf()
|
||||||
|
}
|
||||||
|
|
||||||
protected fun defineTimerJob(builder: NotificationCompat.Builder,
|
protected fun defineTimerJob(builder: NotificationCompat.Builder,
|
||||||
type: NotificationServiceType,
|
type: NotificationServiceType,
|
||||||
timeoutMilliseconds: Long,
|
timeoutMilliseconds: Long,
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ abstract class ExternalSettingsActivity : DatabaseModeActivity() {
|
|||||||
|
|
||||||
private var lockView: FloatingActionButton? = null
|
private var lockView: FloatingActionButton? = null
|
||||||
|
|
||||||
|
override fun manageDatabaseInfo(): Boolean = true
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
|||||||
@@ -27,32 +27,27 @@ import android.view.View
|
|||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.ProgressBar
|
import android.widget.ProgressBar
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import com.kunzisoft.keepass.R
|
import com.kunzisoft.keepass.R
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
open class ProgressTaskDialogFragment : DialogFragment() {
|
open class ProgressTaskDialogFragment : DialogFragment() {
|
||||||
|
|
||||||
@StringRes
|
|
||||||
private var title = UNDEFINED
|
|
||||||
@StringRes
|
|
||||||
private var message = UNDEFINED
|
|
||||||
@StringRes
|
|
||||||
private var warning = UNDEFINED
|
|
||||||
private var cancellable: (() -> Unit)? = null
|
|
||||||
|
|
||||||
private var titleView: TextView? = null
|
private var titleView: TextView? = null
|
||||||
private var messageView: TextView? = null
|
private var messageView: TextView? = null
|
||||||
private var warningView: TextView? = null
|
private var warningView: TextView? = null
|
||||||
private var cancelButton: Button? = null
|
private var cancelButton: Button? = null
|
||||||
private var progressView: ProgressBar? = null
|
private var progressView: ProgressBar? = null
|
||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
private val progressTaskViewModel: ProgressTaskViewModel by activityViewModels()
|
||||||
|
|
||||||
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
try {
|
try {
|
||||||
activity?.let {
|
activity?.let {
|
||||||
val builder = AlertDialog.Builder(it)
|
val builder = AlertDialog.Builder(it)
|
||||||
@@ -71,68 +66,44 @@ open class ProgressTaskDialogFragment : DialogFragment() {
|
|||||||
cancelButton = root.findViewById(R.id.progress_dialog_cancel)
|
cancelButton = root.findViewById(R.id.progress_dialog_cancel)
|
||||||
progressView = root.findViewById(R.id.progress_dialog_bar)
|
progressView = root.findViewById(R.id.progress_dialog_bar)
|
||||||
|
|
||||||
updateTitle(title)
|
|
||||||
updateMessage(message)
|
|
||||||
updateWarning(warning)
|
|
||||||
setCancellable(cancellable)
|
|
||||||
|
|
||||||
isCancelable = false
|
isCancelable = false
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
progressTaskViewModel.progressMessageState.collect { state ->
|
||||||
|
updateView(titleView,
|
||||||
|
state.titleId?.let { title -> getString(title) })
|
||||||
|
updateView(messageView,
|
||||||
|
state.messageId?.let { message -> getString(message) })
|
||||||
|
updateView(warningView,
|
||||||
|
state.warningId?.let { warning -> getString(warning) })
|
||||||
|
cancelButton?.isVisible = state.cancelable != null
|
||||||
|
cancelButton?.setOnClickListener {
|
||||||
|
state.cancelable?.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return builder.create()
|
return builder.create()
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Unable to create progress dialog")
|
Log.e(TAG, "Unable to create progress dialog", e)
|
||||||
}
|
}
|
||||||
return super.onCreateDialog(savedInstanceState)
|
return super.onCreateDialog(savedInstanceState)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setTitle(@StringRes titleId: Int) {
|
private fun updateView(textView: TextView?, value: String?) {
|
||||||
this.title = titleId
|
if (value == null) {
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateView(textView: TextView?, @StringRes resId: Int) {
|
|
||||||
activity?.lifecycleScope?.launch {
|
|
||||||
if (resId == UNDEFINED) {
|
|
||||||
textView?.visibility = View.GONE
|
textView?.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
textView?.setText(resId)
|
textView?.text = value
|
||||||
textView?.visibility = View.VISIBLE
|
textView?.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateCancelable() {
|
|
||||||
activity?.lifecycleScope?.launch {
|
|
||||||
cancelButton?.isVisible = cancellable != null
|
|
||||||
cancelButton?.setOnClickListener {
|
|
||||||
cancellable?.invoke()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateTitle(@StringRes resId: Int?) {
|
|
||||||
this.title = resId ?: UNDEFINED
|
|
||||||
updateView(titleView, title)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateMessage(@StringRes resId: Int?) {
|
|
||||||
this.message = resId ?: UNDEFINED
|
|
||||||
updateView(messageView, message)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateWarning(@StringRes resId: Int?) {
|
|
||||||
this.warning = resId ?: UNDEFINED
|
|
||||||
updateView(warningView, warning)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setCancellable(cancellable: (() -> Unit)?) {
|
|
||||||
this.cancellable = cancellable
|
|
||||||
updateCancelable()
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val TAG = ProgressTaskDialogFragment::class.java.simpleName
|
private val TAG = ProgressTaskDialogFragment::class.java.simpleName
|
||||||
const val PROGRESS_TASK_DIALOG_TAG = "progressDialogFragment"
|
const val PROGRESS_TASK_DIALOG_TAG = "progressDialogFragment"
|
||||||
const val UNDEFINED = -1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.kunzisoft.keepass.tasks
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import com.kunzisoft.keepass.database.ProgressMessage
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
|
||||||
|
class ProgressTaskViewModel: ViewModel() {
|
||||||
|
|
||||||
|
private val mProgressMessageState = MutableStateFlow(ProgressMessage())
|
||||||
|
val progressMessageState: StateFlow<ProgressMessage> = mProgressMessageState
|
||||||
|
|
||||||
|
private val mProgressTaskState = MutableStateFlow<ProgressTaskState>(ProgressTaskState.Stop)
|
||||||
|
val progressTaskState: StateFlow<ProgressTaskState> = mProgressTaskState
|
||||||
|
|
||||||
|
fun update(value: ProgressMessage) {
|
||||||
|
mProgressMessageState.value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
fun start(value: ProgressMessage) {
|
||||||
|
mProgressTaskState.value = ProgressTaskState.Start
|
||||||
|
update(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stop() {
|
||||||
|
mProgressTaskState.value = ProgressTaskState.Stop
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class ProgressTaskState {
|
||||||
|
object Start: ProgressTaskState()
|
||||||
|
object Stop: ProgressTaskState()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -98,25 +98,43 @@ object AppUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val processedPackageNames = mutableSetOf<String>()
|
val processedPackageNames = mutableSetOf<String>()
|
||||||
|
|
||||||
for (resolveInfo in resolveInfoList) {
|
for (resolveInfo in resolveInfoList) {
|
||||||
val packageName = resolveInfo.activityInfo.packageName
|
val packageName = resolveInfo.activityInfo.packageName
|
||||||
if (packageName != null && !processedPackageNames.contains(packageName)) {
|
if (packageName != null && !processedPackageNames.contains(packageName)) {
|
||||||
try {
|
buildAndroidPrivilegedApp(packageManager, packageName)?.let { privilegedApp ->
|
||||||
|
browserList.add(privilegedApp)
|
||||||
|
processedPackageNames.add(packageName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the Play Service
|
||||||
|
val gServices = "com.google.android.gms"
|
||||||
|
buildAndroidPrivilegedApp(packageManager, gServices)?.let { privilegedApp ->
|
||||||
|
browserList.add(privilegedApp)
|
||||||
|
processedPackageNames.add(gServices)
|
||||||
|
}
|
||||||
|
|
||||||
|
return browserList.distinctBy { it.packageName } // Ensure uniqueness just in case
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.P)
|
||||||
|
private fun buildAndroidPrivilegedApp(
|
||||||
|
packageManager: PackageManager,
|
||||||
|
packageName: String
|
||||||
|
): AndroidPrivilegedApp? {
|
||||||
|
return try {
|
||||||
val packageInfo = packageManager.getPackageInfo(
|
val packageInfo = packageManager.getPackageInfo(
|
||||||
packageName,
|
packageName,
|
||||||
PackageManager.GET_SIGNING_CERTIFICATES
|
PackageManager.GET_SIGNING_CERTIFICATES
|
||||||
)
|
)
|
||||||
val signatureFingerprints = packageInfo.signingInfo?.getAllFingerprints()
|
val signatureFingerprints = packageInfo.signingInfo?.getAllFingerprints()
|
||||||
signatureFingerprints?.let {
|
signatureFingerprints?.let {
|
||||||
browserList.add(AndroidPrivilegedApp(packageName, signatureFingerprints))
|
AndroidPrivilegedApp(packageName, signatureFingerprints)
|
||||||
processedPackageNames.add(packageName)
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(AppUtil::class.simpleName, "Error processing package: $packageName", e)
|
Log.e(AppUtil::class.simpleName, "Error processing package: $packageName", e)
|
||||||
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return browserList.distinctBy { it.packageName } // Ensure uniqueness just in case
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -666,4 +666,41 @@
|
|||||||
<string name="passkeys_close_database_title">Sulge andmebaas</string>
|
<string name="passkeys_close_database_title">Sulge andmebaas</string>
|
||||||
<string name="passkeys_privileged_apps_ask_title">Rakendust ei õnnestu tuvastada</string>
|
<string name="passkeys_privileged_apps_ask_title">Rakendust ei õnnestu tuvastada</string>
|
||||||
<string name="warning_overwrite_data_title">Kas soovid olemasolevad andmed üle kirjutada?</string>
|
<string name="warning_overwrite_data_title">Kas soovid olemasolevad andmed üle kirjutada?</string>
|
||||||
|
<string name="warning_overwrite_data_description">Selle toiminguga asendad kirje olemasolevad andmed, aga kui ajaloo logimine on kasutusel, siis saad vanu kirjeid ka hiljem näha.</string>
|
||||||
|
<string name="credential_provider">kasutajanime/salasõna automaattäite teenus</string>
|
||||||
|
<string name="passkeys">WebAuthn pääsuvõtmed</string>
|
||||||
|
<string name="passkeys_explanation_summary">Seadista WebAuthn pääsuvõtmed, mis võimaldavad kiiret ja turvalist salasõnadeta ligipääsu</string>
|
||||||
|
<string name="passkeys_preference_title">Pääsuvõtmete seadistused</string>
|
||||||
|
<string name="passkeys_close_database_summary">Peale pääsuvõtme valimist sulge andmebaas</string>
|
||||||
|
<string name="passkeys_privileged_apps_title">Eesõigustega rakendused</string>
|
||||||
|
<string name="passkeys_privileged_apps_summary">Halda brausereid sinu loodud eesõigustega rakenduste loendis</string>
|
||||||
|
<string name="passkeys_privileged_apps_explanation">HOIATUS: Eesõigustega rakendus toimib lüüsina autentimise algallikaga suhtlemisel. Turvaprobleemide vältimiseks palun taga, et kasutad õiget rakendust.</string>
|
||||||
|
<string name="passkeys_privileged_apps_ask_message">%1$s kaset pääsuvõtmega autentimiseks.\n\nKas lisame ta eesõigustega rakenduste loendisse?</string>
|
||||||
|
<string name="passkeys_missing_signature_app_ask_title">Allkiri on puudu</string>
|
||||||
|
<string name="passkeys_missing_signature_app_ask_explanation">HOAITUS: See pääsuluba on loodud teise kliendi poolt või on allkiri kustutatud. Turvaprobleemide vältimiseks palun kontrolli rakendus, milles soovi end tuvastada on sama teenuse osa ning sisuliselt õige.\n\nKui rakendus on veebibrauser, siis ära lisa allkirja kirje juurde vaid seadistustes leiduva eesõigustega rakenduste loendisse.</string>
|
||||||
|
<string name="passkeys_missing_signature_app_ask_message">%1$s on antud kontekstis tundmatu ja mittetunnustatud ning ta proovib autentimist olemasoleva pääsuvõtmega.</string>
|
||||||
|
<string name="passkeys_missing_signature_app_ask_question">Kas soovid lisada rakenduse allkirja pääsuvõtme kirjele?</string>
|
||||||
|
<string name="passkeys_auto_select_title">Automaatne valik</string>
|
||||||
|
<string name="passkeys_auto_select_summary">Vali automaatselt vaid siis, kui vaid üks kirje ja andmebaas on avatud ning vaid siis, kui rakendus ühildub</string>
|
||||||
|
<string name="passkeys_backup_eligibility_title">Varunduse kõlblikkus</string>
|
||||||
|
<string name="passkeys_backup_eligibility_summary">Otsusta loomise hetkel, kas avaliku võtme allikat on lubatud varundada</string>
|
||||||
|
<string name="passkeys_backup_state_title">Varunduse olek</string>
|
||||||
|
<string name="passkeys_backup_state_summary">Anna märku, kas autentimisandmed on varundatud ja kaitstud üksiku seadme kaotsimineku puhul</string>
|
||||||
|
<string name="credential_provider_service_subtitle">Pääsuvõtmed - automaattäite teenusepakkuja</string>
|
||||||
|
<string name="passkey">WebAuthn pääsuvõti</string>
|
||||||
|
<string name="passkey_service_name">KeePassDX autentimisteenusepakkuja</string>
|
||||||
|
<string name="passkey_creation_description">Salvesta pääsuvõti uue kirjena</string>
|
||||||
|
<string name="passkey_update_description">Uuenda pääsuvõtit: %1$s</string>
|
||||||
|
<string name="passkey_selection_username">Pääsuvõtit ei leidu</string>
|
||||||
|
<string name="passkey_selection_description">Vali olemasolev pääsuvõti</string>
|
||||||
|
<string name="passkey_database_username">KeePassDX-i andmebaas</string>
|
||||||
|
<string name="passkey_locked_database_description">Vali lukustuse eemaldamiseks</string>
|
||||||
|
<string name="passkey_username">Pääsuvõtme kasutajanimi</string>
|
||||||
|
<string name="passkey_private_key">Pääsuvõtme privaatvõti</string>
|
||||||
|
<string name="passkey_credential_id">Pääsuvõtme autentimisühiku tunnus</string>
|
||||||
|
<string name="passkey_user_handle">Pääsuvõtme kasutaja võrgutunnus</string>
|
||||||
|
<string name="passkey_relying_party">Pääsuvõtit edastav osapool</string>
|
||||||
|
<string name="passkey_backup_eligibility">Pääsuvõtme kõlblikkus varundamiseks</string>
|
||||||
|
<string name="passkey_backup_state">Pääsuvõtme varunduse olek</string>
|
||||||
|
<string name="error_passkey_result">Pääsuvõtme väljastamine vastuseks ei õnnestu</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
--><resources>
|
--><resources>
|
||||||
<string name="feedback">피드백</string>
|
<string name="feedback">피드백</string>
|
||||||
<string name="homepage">홈페이지</string>
|
<string name="homepage">홈페이지</string>
|
||||||
<string name="about_description">KeePass 암호 관리자의 Android 구현본</string>
|
<string name="about_description">KeePass 암호 관리자의 Android 구현체.</string>
|
||||||
<string name="accept">확인</string>
|
<string name="accept">확인</string>
|
||||||
<string name="add_entry">항목 추가</string>
|
<string name="add_entry">항목 추가</string>
|
||||||
<string name="edit_entry">항목 수정</string>
|
<string name="edit_entry">항목 수정</string>
|
||||||
@@ -40,14 +40,13 @@
|
|||||||
<string name="clipboard_error_clear">클립보드를 비울 수 없음</string>
|
<string name="clipboard_error_clear">클립보드를 비울 수 없음</string>
|
||||||
<string name="clipboard_timeout">클립보드 시간 초과</string>
|
<string name="clipboard_timeout">클립보드 시간 초과</string>
|
||||||
<string name="clipboard_timeout_summary">클립보드 저장이 유지될 시간 (장치가 지원한다면)</string>
|
<string name="clipboard_timeout_summary">클립보드 저장이 유지될 시간 (장치가 지원한다면)</string>
|
||||||
<string name="select_to_copy">%1$s 을(를) 클립보드에 복사하려면 선택하십시오.</string>
|
<string name="select_to_copy">%1$s 을(를) 클립보드에 복사하기</string>
|
||||||
<string name="retrieving_db_key">데이터베이스 키를 검색하는 중…</string>
|
<string name="retrieving_db_key">데이터베이스 키를 검색하는 중…</string>
|
||||||
<string name="database">데이터베이스</string>
|
<string name="database">데이터베이스</string>
|
||||||
<string name="decrypting_db">데이터베이스 컨텐츠 암호 해독 중…</string>
|
<string name="decrypting_db">데이터베이스 컨텐츠 암호 해독 중…</string>
|
||||||
<string name="default_checkbox">기본 데이터베이스로 사용</string>
|
<string name="default_checkbox">기본 데이터베이스로 사용</string>
|
||||||
<string name="digits">단위</string>
|
<string name="digits">단위</string>
|
||||||
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft는 보증이 적용되지 않습니다; 이것은 자유 소프트웨어이며, 광고가 없습니다.
|
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft는 보증이 적용되지 않습니다; 이것은 <strong>자유 소프트웨어</strong>이며, <strong>광고가 없습니다</strong>. \n이 것은 보증 없이 있는 그대로, <strong>GPL 버전 3</strong> 라이선스로 제공됩니다.</string>
|
||||||
\n이 것은 보증 없이 있는 그대로, GPL 버전 3하에 제공됩니다.</string>
|
|
||||||
<string name="entry_accessed">접근됨</string>
|
<string name="entry_accessed">접근됨</string>
|
||||||
<string name="entry_cancel">취소</string>
|
<string name="entry_cancel">취소</string>
|
||||||
<string name="entry_notes">노트</string>
|
<string name="entry_notes">노트</string>
|
||||||
@@ -81,22 +80,22 @@
|
|||||||
<string name="field_name">필드 이름</string>
|
<string name="field_name">필드 이름</string>
|
||||||
<string name="field_value">필드 값</string>
|
<string name="field_value">필드 값</string>
|
||||||
<string name="file_not_found_content">파일을 찾을 수 없습니다. 파일 탐색기에서 열리는지 확인해 주세요.</string>
|
<string name="file_not_found_content">파일을 찾을 수 없습니다. 파일 탐색기에서 열리는지 확인해 주세요.</string>
|
||||||
<string name="file_browser">파일 탐색기</string>
|
<string name="file_browser">파일 관리자</string>
|
||||||
<string name="generate_password">비밀번호 생성</string>
|
<string name="generate_password">비밀번호 생성</string>
|
||||||
<string name="hint_conf_pass">비밀번호 확인</string>
|
<string name="hint_conf_pass">패스워드 확인</string>
|
||||||
<string name="hint_generated_password">생성된 비밀번호</string>
|
<string name="hint_generated_password">생성된 패스워드</string>
|
||||||
<string name="hint_group_name">그룹 이름</string>
|
<string name="hint_group_name">그룹 이름</string>
|
||||||
<string name="hint_keyfile">키 파일</string>
|
<string name="hint_keyfile">키 파일</string>
|
||||||
<string name="hint_length">길이</string>
|
<string name="hint_length">길이</string>
|
||||||
<string name="hint_pass">비밀번호</string>
|
<string name="hint_pass">패스워드</string>
|
||||||
<string name="password">비밀번호</string>
|
<string name="password">비밀번호</string>
|
||||||
<string name="invalid_credentials">비밀번호나 키 파일을 읽을 수 없습니다.</string>
|
<string name="invalid_credentials">패스워드나 키 파일을 읽을 수 없습니다.</string>
|
||||||
<string name="invalid_algorithm">잘못된 알고리즘입니다.</string>
|
<string name="invalid_algorithm">잘못된 알고리즘입니다.</string>
|
||||||
<string name="invalid_db_sig">데이터베이스 형식을 인식할 수 없습니다.</string>
|
<string name="invalid_db_sig">데이터베이스 형식을 인식할 수 없습니다.</string>
|
||||||
<string name="keyfile_is_empty">이 키 파일은 비어 있습니다.</string>
|
<string name="keyfile_is_empty">이 키 파일은 비어 있습니다.</string>
|
||||||
<string name="length">길이</string>
|
<string name="length">길이</string>
|
||||||
<string name="list_entries_show_username_title">아이디 보이기</string>
|
<string name="list_entries_show_username_title">아이디 보이기</string>
|
||||||
<string name="list_entries_show_username_summary">엔트리 목록에 아이디 보이기</string>
|
<string name="list_entries_show_username_summary">항목 리스트에 사용자 이름을 표시합니다</string>
|
||||||
<string name="list_size_title">리스트 항목 크기</string>
|
<string name="list_size_title">리스트 항목 크기</string>
|
||||||
<string name="list_size_summary">요소 목록 텍스트 크기</string>
|
<string name="list_size_summary">요소 목록 텍스트 크기</string>
|
||||||
<string name="loading_database">데이터베이스 로딩 중…</string>
|
<string name="loading_database">데이터베이스 로딩 중…</string>
|
||||||
@@ -105,7 +104,7 @@
|
|||||||
<string name="hide_password_summary">기본 비밀번호를 (***) 로 가리기</string>
|
<string name="hide_password_summary">기본 비밀번호를 (***) 로 가리기</string>
|
||||||
<string name="about">정보</string>
|
<string name="about">정보</string>
|
||||||
<string name="menu_change_key_settings">마스터 키 바꾸기</string>
|
<string name="menu_change_key_settings">마스터 키 바꾸기</string>
|
||||||
<string name="copy_field">%1$s 복사됨</string>
|
<string name="copy_field">%1$s의 사본</string>
|
||||||
<string name="settings">설정</string>
|
<string name="settings">설정</string>
|
||||||
<string name="menu_app_settings">앱 설정</string>
|
<string name="menu_app_settings">앱 설정</string>
|
||||||
<string name="menu_form_filling_settings">폼 채우기</string>
|
<string name="menu_form_filling_settings">폼 채우기</string>
|
||||||
@@ -129,8 +128,8 @@
|
|||||||
<string name="never">절대 하지 않음</string>
|
<string name="never">절대 하지 않음</string>
|
||||||
<string name="no_results">검색 결과가 없음</string>
|
<string name="no_results">검색 결과가 없음</string>
|
||||||
<string name="no_url_handler">이 URL을 열기 위해 웹 브라우저를 설치하십시오.</string>
|
<string name="no_url_handler">이 URL을 열기 위해 웹 브라우저를 설치하십시오.</string>
|
||||||
<string name="select_database_file">가지고 있는 데이터베이스 열기</string>
|
<string name="select_database_file">기존 저장소 열기</string>
|
||||||
<string name="create_keepass_file">새 데이터베이스 생성</string>
|
<string name="create_keepass_file">새 저장소 생성</string>
|
||||||
<string name="progress_create">새 데이터베이스 생성 중…</string>
|
<string name="progress_create">새 데이터베이스 생성 중…</string>
|
||||||
<string name="progress_title">작업 중…</string>
|
<string name="progress_title">작업 중…</string>
|
||||||
<string name="protection">보호</string>
|
<string name="protection">보호</string>
|
||||||
@@ -138,7 +137,7 @@
|
|||||||
<string name="read_only_warning">KeePassDX는 데이터베이스를 수정하기 위해 쓰기 권한이 필요합니다.</string>
|
<string name="read_only_warning">KeePassDX는 데이터베이스를 수정하기 위해 쓰기 권한이 필요합니다.</string>
|
||||||
<string name="content_description_remove_from_list">삭제</string>
|
<string name="content_description_remove_from_list">삭제</string>
|
||||||
<string name="root">루트</string>
|
<string name="root">루트</string>
|
||||||
<string name="encryption_explanation">데이터베이스 암호화 알고리즘이 모든 데이터에 적용됩니다.</string>
|
<string name="encryption_explanation">데이터베이스 암호화 알고리즘이 모든 데이터에 적용됩니다</string>
|
||||||
<string name="memory_usage">메모리 사용량</string>
|
<string name="memory_usage">메모리 사용량</string>
|
||||||
<string name="memory_usage_explanation">바이너리 바이트 단위의 메모리 용량이 키 파생 기능에 사용됩니다.</string>
|
<string name="memory_usage_explanation">바이너리 바이트 단위의 메모리 용량이 키 파생 기능에 사용됩니다.</string>
|
||||||
<string name="saving_database">데이터베이스 저장 중…</string>
|
<string name="saving_database">데이터베이스 저장 중…</string>
|
||||||
@@ -250,10 +249,10 @@
|
|||||||
<string name="error_field_name_already_exists">그 필드 이름은 이미 존재합니다.</string>
|
<string name="error_field_name_already_exists">그 필드 이름은 이미 존재합니다.</string>
|
||||||
<string name="inherited">상속</string>
|
<string name="inherited">상속</string>
|
||||||
<string name="auto_type">자동입력</string>
|
<string name="auto_type">자동입력</string>
|
||||||
<string name="warning_database_already_opened">데이터베이스가 이미 열려있습니다. 새 것을 열려면 지금 것을 먼저 닫아주세요.</string>
|
<string name="warning_database_already_opened">데이터베이스가 이미 열려있습니다. 새 것을 열려면 지금 것을 먼저 닫아주세요</string>
|
||||||
<string name="hide_broken_locations_summary">최근 데이터베이스 목록에서 파손된 링크를 감춤</string>
|
<string name="hide_broken_locations_summary">최근 데이터베이스 목록에서 파손된 링크를 감춤</string>
|
||||||
<string name="import_app_properties_summary">앱 속성을 내보낼 파일을 선택</string>
|
<string name="import_app_properties_summary">가져올 앱 설정 파일 선택</string>
|
||||||
<string name="success_import_app_properties">앱 속성을 가져왔습니다.</string>
|
<string name="success_import_app_properties">앱 설정 가져옴</string>
|
||||||
<string name="kdf_explanation">암호화 알고리즘 용 키를 생성하기 위해, 마스터키는 임의의 솔트(salt) 키 파생 함수를 사용하여 변환됩니다.</string>
|
<string name="kdf_explanation">암호화 알고리즘 용 키를 생성하기 위해, 마스터키는 임의의 솔트(salt) 키 파생 함수를 사용하여 변환됩니다.</string>
|
||||||
<string name="warning">경고</string>
|
<string name="warning">경고</string>
|
||||||
<string name="error_challenge_already_requested">이미 요청된 시도입니다.</string>
|
<string name="error_challenge_already_requested">이미 요청된 시도입니다.</string>
|
||||||
@@ -262,14 +261,14 @@
|
|||||||
<string name="error_response_already_provided">이미 응답했습니다.</string>
|
<string name="error_response_already_provided">이미 응답했습니다.</string>
|
||||||
<string name="error_location_unknown">데이터 베이스 위치를 알 수 없어 데이터 베이스 액션을 수행할 수 없습니다.</string>
|
<string name="error_location_unknown">데이터 베이스 위치를 알 수 없어 데이터 베이스 액션을 수행할 수 없습니다.</string>
|
||||||
<string name="error_driver_required">%1$s 를 위한 드라이버가 요구됩니다.</string>
|
<string name="error_driver_required">%1$s 를 위한 드라이버가 요구됩니다.</string>
|
||||||
<string name="error_unable_merge_database_kdb">데이터베이스 V1로부터 병합할 수 없습니다.</string>
|
<string name="error_unable_merge_database_kdb">kdb 데이터베이스 파일과 병합할 수 없습니다.</string>
|
||||||
<string name="error_hardware_key_unsupported">하드웨어 키는 지원하지 않습니다.</string>
|
<string name="error_hardware_key_unsupported">하드웨어 키는 지원하지 않습니다.</string>
|
||||||
<string name="error_empty_key">키는 반드시 입력해야 합니다.</string>
|
<string name="error_empty_key">키는 반드시 입력해야 합니다.</string>
|
||||||
<string name="hint_icon_name">아이콘명</string>
|
<string name="hint_icon_name">아이콘명</string>
|
||||||
<string name="passphrase">암호문</string>
|
<string name="passphrase">암호문</string>
|
||||||
<string name="colorize_password_title">비밀번호에 색상 부여</string>
|
<string name="colorize_password_title">비밀번호에 색상 부여</string>
|
||||||
<string name="colorize_password_summary">타입에 따라 비밀번호 문자에 색상을 부여</string>
|
<string name="colorize_password_summary">타입에 따라 비밀번호 문자에 색상을 부여</string>
|
||||||
<string name="export_app_properties_title">앱 속성을 내보내기</string>
|
<string name="export_app_properties_title">앱 설정 내보내기</string>
|
||||||
<string name="uppercase">대문자</string>
|
<string name="uppercase">대문자</string>
|
||||||
<string name="menu_security_settings">보안 설정</string>
|
<string name="menu_security_settings">보안 설정</string>
|
||||||
<string name="menu_reload_database">데이터 다시 읽기</string>
|
<string name="menu_reload_database">데이터 다시 읽기</string>
|
||||||
@@ -280,7 +279,7 @@
|
|||||||
<string name="save_mode">저장 모드</string>
|
<string name="save_mode">저장 모드</string>
|
||||||
<string name="selection_mode">선택 모드</string>
|
<string name="selection_mode">선택 모드</string>
|
||||||
<string name="remember_hardware_key_title">하드웨어 키를 기억</string>
|
<string name="remember_hardware_key_title">하드웨어 키를 기억</string>
|
||||||
<string name="export_app_properties_summary">앱 속성을 내보낼 파일을 생성</string>
|
<string name="export_app_properties_summary">앱 설정을 내보내기 위해 파일 생성</string>
|
||||||
<string name="error_import_app_properties">앱 속성을 가져오던 중 오류 발생.</string>
|
<string name="error_import_app_properties">앱 속성을 가져오던 중 오류 발생.</string>
|
||||||
<string name="contains_duplicate_uuid">데이터베이스가 중복된 UUID를 포함하고 있습니다.</string>
|
<string name="contains_duplicate_uuid">데이터베이스가 중복된 UUID를 포함하고 있습니다.</string>
|
||||||
<string name="remember_database_locations_summary">데이터 베이스가 저장된 곳을 추적</string>
|
<string name="remember_database_locations_summary">데이터 베이스가 저장된 곳을 추적</string>
|
||||||
@@ -311,7 +310,7 @@
|
|||||||
<string name="menu_restore_entry_history">이력을 복구</string>
|
<string name="menu_restore_entry_history">이력을 복구</string>
|
||||||
<string name="subdomain_search_summary">보조 도메인 제한하에 웹 도메인을 검색</string>
|
<string name="subdomain_search_summary">보조 도메인 제한하에 웹 도메인을 검색</string>
|
||||||
<string name="contains_duplicate_uuid_procedure">중복에 대해 새로운 UUID를 생성하여 문제를 해결하고 진행할까요\?</string>
|
<string name="contains_duplicate_uuid_procedure">중복에 대해 새로운 UUID를 생성하여 문제를 해결하고 진행할까요\?</string>
|
||||||
<string name="success_export_app_properties">앱 속성을 내보냈습니다.</string>
|
<string name="success_export_app_properties">앱 설정 내보냄</string>
|
||||||
<string name="parallelism">병렬 처리</string>
|
<string name="parallelism">병렬 처리</string>
|
||||||
<string name="command_execution">명령 실행중…</string>
|
<string name="command_execution">명령 실행중…</string>
|
||||||
<string name="menu_master_key_settings">마스터 키 설정</string>
|
<string name="menu_master_key_settings">마스터 키 설정</string>
|
||||||
@@ -321,14 +320,14 @@
|
|||||||
<string name="menu_device_unlock_settings">고급 잠금 해제</string>
|
<string name="menu_device_unlock_settings">고급 잠금 해제</string>
|
||||||
<string name="search_mode">검색 모드</string>
|
<string name="search_mode">검색 모드</string>
|
||||||
<string name="rounds_explanation">추가적인 암호화 차수를 설정함으로써 무차별 대입 공격(brute force attack)에 대한 방어를 강화할 수 있습니다. 대신 읽기/저장시 느려질 수 있습니다.</string>
|
<string name="rounds_explanation">추가적인 암호화 차수를 설정함으로써 무차별 대입 공격(brute force attack)에 대한 방어를 강화할 수 있습니다. 대신 읽기/저장시 느려질 수 있습니다.</string>
|
||||||
<string name="do_not_kill_app">앱을 강제 종료하지 마세요.</string>
|
<string name="do_not_kill_app">앱을 강제 종료하지 마세요…</string>
|
||||||
<string name="sort_recycle_bin_bottom">휴지통을 바닥에</string>
|
<string name="sort_recycle_bin_bottom">휴지통을 바닥에</string>
|
||||||
<string name="warning_database_link_revoked">파일에 대한 접근이 파일 관리자에 의해 철회되었습니다.</string>
|
<string name="warning_database_link_revoked">파일에 대한 접근이 파일 관리자에 의해 철회되었습니다</string>
|
||||||
<string name="hide_broken_locations_title">파손된 데이터페이스 링크를 감춤</string>
|
<string name="hide_broken_locations_title">파손된 데이터페이스 링크를 감춤</string>
|
||||||
<string name="import_app_properties_title">앱 속성을 가져오기</string>
|
<string name="import_app_properties_title">앱 설정 가져오기</string>
|
||||||
<string name="error_export_app_properties">앱 속성을 내보내던 중 오류 발생.</string>
|
<string name="error_export_app_properties">앱 속성을 내보내던 중 오류 발생.</string>
|
||||||
<string name="rounds">변환 차수</string>
|
<string name="rounds">변환 차수</string>
|
||||||
<string name="parallelism_explanation">키 파생 함수에 사용되는 병렬 처리 수준 (즉, 스레드의 갯수)</string>
|
<string name="parallelism_explanation">키 파생 함수에 사용되는 병렬 처리 수준(즉, 스레드의 갯수).</string>
|
||||||
<string name="html_about_privacy"><strong>사용자 데이터를 받아오지 않습니다.</strong> 어떤 서버에도 연결하지 않고 로컬로만 동작하며 사용자의 사생활(프라이버시)를 최우선시합니다.</string>
|
<string name="html_about_privacy"><strong>사용자 데이터를 받아오지 않습니다.</strong> 어떤 서버에도 연결하지 않고 로컬로만 동작하며 사용자의 사생활(프라이버시)를 최우선시합니다.</string>
|
||||||
<string name="error_rebuild_list">목록 재구축을 알맞게 할 수 없습니다.</string>
|
<string name="error_rebuild_list">목록 재구축을 알맞게 할 수 없습니다.</string>
|
||||||
<string name="error_file_to_big">업로드하려는 파일이 너무 큽니다.</string>
|
<string name="error_file_to_big">업로드하려는 파일이 너무 큽니다.</string>
|
||||||
@@ -339,50 +338,50 @@
|
|||||||
<string name="show_otp_token_summary">항목 목록에서 OTP 토큰을 표시</string>
|
<string name="show_otp_token_summary">항목 목록에서 OTP 토큰을 표시</string>
|
||||||
<string name="show_uuid_title">UUID를 표시</string>
|
<string name="show_uuid_title">UUID를 표시</string>
|
||||||
<string name="show_uuid_summary">항목이나 그룹에 연결된 UUID를 표시</string>
|
<string name="show_uuid_summary">항목이나 그룹에 연결된 UUID를 표시</string>
|
||||||
<string name="creating_database">데이터 베이스를 생성</string>
|
<string name="creating_database">데이터베이스 생성중…</string>
|
||||||
<string name="menu_merge_database">데이터 병합</string>
|
<string name="menu_merge_database">데이터 병합</string>
|
||||||
<string name="menu_merge_from">... 로부터 병합</string>
|
<string name="menu_merge_from">…로부터 병합</string>
|
||||||
<string name="menu_save_copy_to">... 에 복사본 저장</string>
|
<string name="menu_save_copy_to">…에 복사본 저장</string>
|
||||||
<string name="menu_keystore_remove_key">고급 잠금 해제 키를 삭제</string>
|
<string name="menu_keystore_remove_key">디바이스 잠금 해제 키 삭제</string>
|
||||||
<string name="sort_last_access_time">접근</string>
|
<string name="sort_last_access_time">접근</string>
|
||||||
<string name="invalid_db_same_uuid">%1$s 와 동일한 UUID %2$s 가 이미 존재합니다.</string>
|
<string name="invalid_db_same_uuid">%1$s 와 동일한 UUID %2$s 가 이미 존재합니다.</string>
|
||||||
<string name="underline">밑줄</string>
|
<string name="underline">밑줄</string>
|
||||||
<string name="unsupported_db_version">지원하지 않는 데이터베이스 버전입니다.</string>
|
<string name="unsupported_db_version">지원하지 않는 데이터베이스 버전입니다.</string>
|
||||||
<string name="permission">허용</string>
|
<string name="permission">권한</string>
|
||||||
<string name="menu_appearance_settings">테마</string>
|
<string name="menu_appearance_settings">테마</string>
|
||||||
<string name="biometric">생체 인증</string>
|
<string name="biometric">생체 인증</string>
|
||||||
<string name="device_credential">기기 자격 증명</string>
|
<string name="device_credential">기기 자격 증명</string>
|
||||||
<string name="generate_keyfile">키 파일 생성하기</string>
|
<string name="generate_keyfile">키 파일 생성하기</string>
|
||||||
<string name="menu_form_filling_settings_summary">키보드, 자동 완성, 클립보드</string>
|
<string name="menu_form_filling_settings_summary">키보드, 자동 완성, 클립보드</string>
|
||||||
<string name="menu_app_settings_summary">검색, 잠금, 기록, 속성</string>
|
<string name="menu_app_settings_summary">검색, 잠금, 기록, 속성</string>
|
||||||
<string name="merge_success">병합을 성공했습니다</string>
|
<string name="merge_success">병합이 성공적으로 완료되었습니다</string>
|
||||||
<string name="version_label">버전 %1$s</string>
|
<string name="version_label">버전 %1$s</string>
|
||||||
<string name="encrypted_value_stored">암호화된 비밀번호가 저장되었습니다</string>
|
<string name="encrypted_value_stored">암호화된 비밀번호가 저장되었습니다</string>
|
||||||
<string name="info">정보</string>
|
<string name="info">정보</string>
|
||||||
<string name="build_label">빌드 %1$s</string>
|
<string name="build_label">빌드 %1$s</string>
|
||||||
<string name="configure_biometric">생체 인식 또는 장치 자격 증명이 등록되지 않았습니다.</string>
|
<string name="configure_biometric">생체 인식 또는 장치 자격 증명이 등록되지 않았습니다.</string>
|
||||||
<string name="properties">속성</string>
|
<string name="properties">속성</string>
|
||||||
<string name="menu_appearance_settings_summary">테마, 색상, 속성</string>
|
<string name="menu_appearance_settings_summary">테마, 색상, 아이콘, 글꼴, 속성</string>
|
||||||
<string name="autofill">자동 입력</string>
|
<string name="autofill">자동 입력</string>
|
||||||
<string name="credential_before_click_device_unlock_button">비밀번호 입력 후 이 버튼을 눌러주세요</string>
|
<string name="credential_before_click_device_unlock_button">비밀번호 입력 후 이 버튼을 눌러주세요.</string>
|
||||||
<string name="unavailable">사용할 수 없습니다</string>
|
<string name="unavailable">사용 불가</string>
|
||||||
<string name="database_history">기록</string>
|
<string name="database_history">이력</string>
|
||||||
<string name="type">유형</string>
|
<string name="type">유형</string>
|
||||||
<string name="configure">설정</string>
|
<string name="configure">설정</string>
|
||||||
<string name="biometric_security_update_required">등록된 생체정보를 업데이트해 주세요.</string>
|
<string name="biometric_security_update_required">등록된 생체정보를 업데이트해 주세요.</string>
|
||||||
<string name="autofill_select_entry">항목을 선택하세요</string>
|
<string name="autofill_select_entry">항목 선택…</string>
|
||||||
<string name="clipboard">클립보드</string>
|
<string name="clipboard">클립보드</string>
|
||||||
<string name="clipboard_notifications_title">클립보드 알림</string>
|
<string name="clipboard_notifications_title">클립보드 알림</string>
|
||||||
<string name="lock_database_screen_off_summary">화면이 꺼지면 몇 초 후에 데이터베이스를 잠급니다.</string>
|
<string name="lock_database_screen_off_summary">화면이 꺼지면 몇 초 후에 데이터베이스를 잠급니다</string>
|
||||||
<string name="lock_database_back_root_title">\'뒤로가기\'를 눌러 잠금</string>
|
<string name="lock_database_back_root_title">\'뒤로가기\'를 눌러 잠금</string>
|
||||||
<string name="unavailable_feature_text">이 기능을 사용할 수 없습니다.</string>
|
<string name="unavailable_feature_text">이 기능을 사용할 수 없습니다.</string>
|
||||||
<string name="lock_database_show_button_summary">UI에 잠금버튼을 표시합니다</string>
|
<string name="lock_database_show_button_summary">UI에 잠금버튼을 표시합니다</string>
|
||||||
<string name="lock_database_back_root_summary">사용자가 뒤로 가기 버튼을 누르면 데이터베이스를 잠급니다</string>
|
<string name="lock_database_back_root_summary">데이터베이스 루트 화면에 있는 경우 \'뒤로\' 버튼을 눌러 데이터베이스를 잠그십시오</string>
|
||||||
<string name="lock_database_show_button_title">잠금 버튼 표시</string>
|
<string name="lock_database_show_button_title">잠금 버튼 표시</string>
|
||||||
<string name="unlock">잠금 해제</string>
|
<string name="unlock">잠금 해제</string>
|
||||||
<string name="lock">잠금</string>
|
<string name="lock">잠금</string>
|
||||||
<string name="autofill_sign_in_prompt">KeePassDX로 로그인</string>
|
<string name="autofill_sign_in_prompt">KeePassDX로 로그인</string>
|
||||||
<string name="password_size_title">생성된 비밀번호 크기</string>
|
<string name="password_size_title">생성된 패스워드 길이</string>
|
||||||
<string name="autofill_preference_title">자동 완성 설정</string>
|
<string name="autofill_preference_title">자동 완성 설정</string>
|
||||||
<string name="set_credential_provider_service_title">기본 자동완성 서비스 설정</string>
|
<string name="set_credential_provider_service_title">기본 자동완성 서비스 설정</string>
|
||||||
<string name="lock_database_screen_off_title">화면 꺼짐 시 잠금</string>
|
<string name="lock_database_screen_off_title">화면 꺼짐 시 잠금</string>
|
||||||
|
|||||||
@@ -475,7 +475,7 @@
|
|||||||
<string name="autofill_ask_to_save_data_summary">Запрашивать сохранение данных после завершения заполнения формы</string>
|
<string name="autofill_ask_to_save_data_summary">Запрашивать сохранение данных после завершения заполнения формы</string>
|
||||||
<string name="autofill_ask_to_save_data_title">Запрос сохранения данных</string>
|
<string name="autofill_ask_to_save_data_title">Запрос сохранения данных</string>
|
||||||
<string name="autofill_close_database_summary">Закрывать базу после выбора автозаполнения</string>
|
<string name="autofill_close_database_summary">Закрывать базу после выбора автозаполнения</string>
|
||||||
<string name="autofill_close_database_title">Закрыть базу</string>
|
<string name="autofill_close_database_title">Закрывать базу</string>
|
||||||
<string name="notification">Уведомление</string>
|
<string name="notification">Уведомление</string>
|
||||||
<string name="biometric_security_update_required">Требуется обновление биометрической системы безопасности.</string>
|
<string name="biometric_security_update_required">Требуется обновление биометрической системы безопасности.</string>
|
||||||
<string name="warning_empty_recycle_bin">Удалить всё содержимое корзины безвозвратно\?</string>
|
<string name="warning_empty_recycle_bin">Удалить всё содержимое корзины безвозвратно\?</string>
|
||||||
@@ -585,7 +585,7 @@
|
|||||||
<string name="show_otp_token_summary">Показывать токены OTP в списке записей</string>
|
<string name="show_otp_token_summary">Показывать токены OTP в списке записей</string>
|
||||||
<string name="menu_external_icon">Внешний значок</string>
|
<string name="menu_external_icon">Внешний значок</string>
|
||||||
<string name="autofill_select_entry">Выбор записи…</string>
|
<string name="autofill_select_entry">Выбор записи…</string>
|
||||||
<string name="autofill_manual_selection_summary">Показывать функцию, позволяющую пользователю вручную выбирать запись из базы</string>
|
<string name="autofill_manual_selection_summary">Показывать элемент управления для ручного выбора пользователем записи из базы</string>
|
||||||
<string name="autofill_manual_selection_title">Ручной выбор</string>
|
<string name="autofill_manual_selection_title">Ручной выбор</string>
|
||||||
<string name="hint_icon_name">Название значка</string>
|
<string name="hint_icon_name">Название значка</string>
|
||||||
<string name="permission">Разрешение</string>
|
<string name="permission">Разрешение</string>
|
||||||
|
|||||||
@@ -569,7 +569,7 @@
|
|||||||
<string name="icon_pack_choose_summary">Paketë ikonash të përdorura te aplikacioni</string>
|
<string name="icon_pack_choose_summary">Paketë ikonash të përdorura te aplikacioni</string>
|
||||||
<string name="hide_expired_entries_summary">Zërat e skaduar nuk shfaqen</string>
|
<string name="hide_expired_entries_summary">Zërat e skaduar nuk shfaqen</string>
|
||||||
<string name="set_credential_provider_service_title">Caktoni shërbim parazgjedhje vetëplotësimesh</string>
|
<string name="set_credential_provider_service_title">Caktoni shërbim parazgjedhje vetëplotësimesh</string>
|
||||||
<string name="autofill_explanation_summary">Aktivizoni vetëplotësimet, për të plotësuar shpejt formularë në aplikacione të tjerë</string>
|
<string name="autofill_explanation_summary">Formësoni vetëplotësimet, për të plotësuar shpejt formularë në aplikacione të tjerë</string>
|
||||||
<string name="autofill_preference_title">Rregullime vetëplotësimi</string>
|
<string name="autofill_preference_title">Rregullime vetëplotësimi</string>
|
||||||
<string name="password_size_summary">Cakton madhësinë parazgjedhje për fjalëkalimet e prodhuar</string>
|
<string name="password_size_summary">Cakton madhësinë parazgjedhje për fjalëkalimet e prodhuar</string>
|
||||||
<string name="list_password_generator_options_summary">Caktoni shenja të lejuara për prodhuesin e fjalëkalimeve</string>
|
<string name="list_password_generator_options_summary">Caktoni shenja të lejuara për prodhuesin e fjalëkalimeve</string>
|
||||||
@@ -623,14 +623,14 @@
|
|||||||
<string name="education_field_copy_summary">Ç’kopjohet te fusha, mund të ngjitet kudo.\n\nPërdorni metodën mbushje formularësh, nëse parapëlqeni.</string>
|
<string name="education_field_copy_summary">Ç’kopjohet te fusha, mund të ngjitet kudo.\n\nPërdorni metodën mbushje formularësh, nëse parapëlqeni.</string>
|
||||||
<string name="education_donation_summary">Ndihmoni të shtohet qëndrueshmëria, siguria dhe në shtimin e më tepër veçorive.</string>
|
<string name="education_donation_summary">Ndihmoni të shtohet qëndrueshmëria, siguria dhe në shtimin e më tepër veçorive.</string>
|
||||||
<string name="html_text_ad_free">Ndryshe nga shumë aplikacione administrimi fjalëkalimesh, ky është <strong>pa reklama</strong>, <strong><em>software</em> i lirë në <em>copylef</em></strong> dhe s’grumbullon të dhëna personale në shërbyesit e tij, pavarësisht versionit që përdorni.</string>
|
<string name="html_text_ad_free">Ndryshe nga shumë aplikacione administrimi fjalëkalimesh, ky është <strong>pa reklama</strong>, <strong><em>software</em> i lirë në <em>copylef</em></strong> dhe s’grumbullon të dhëna personale në shërbyesit e tij, pavarësisht versionit që përdorni.</string>
|
||||||
<string name="html_text_buy_pro">Duke blerë versionin Pro, do të mund të përdorni këtë <strong>stil pamor</strong> dhe do të ndihmoni veçanërisht në <strong>realizimin e projekteve të bashkësisë.<strong></string>
|
<string name="html_text_buy_pro">Duke blerë versionin Pro, do të mund të përdorni këtë <strong>stil pamor</strong> dhe do të ndihmoni veçanërisht në <strong>realizimin e projekteve të bashkësisë.</strong></string>
|
||||||
<string name="error_arc4">S’mbulohet shifër “Arcfour stream”.</string>
|
<string name="error_arc4">S’mbulohet shifër “Arcfour stream”.</string>
|
||||||
<string name="warning_file_too_big">Një bazë të dhënash KeePass supozohet se përmban vetëm kartela të vockla mjetesh (b.f., kartela kyçesh PGP).\n\nMe këtë ngarkim baza juaj e të dhënave mund të bëhet shumë e madhe dhe të ulet funksionimi i saj.</string>
|
<string name="warning_file_too_big">Një bazë të dhënash KeePass supozohet se përmban vetëm kartela të vockla mjetesh (b.f., kartela kyçesh PGP).\n\nMe këtë ngarkim baza juaj e të dhënave mund të bëhet shumë e madhe dhe të ulet funksionimi i saj.</string>
|
||||||
<string name="education_read_only_summary">Ndryshoni mënyrë hapjeje për këtë sesion. \n \n“Mbrojtur nga shkimi” parandalon ndryshime të paqëllimta te baza e të dhënave. \n“E ndryshueshme” ju lejon të shtoni, fshini ose ndryshoni krejt elementët, sipas dëshirës.</string>
|
<string name="education_read_only_summary">Ndryshoni mënyrë hapjeje për këtë sesion. \n \n“Mbrojtur nga shkimi” parandalon ndryshime të paqëllimta te baza e të dhënave. \n“E ndryshueshme” ju lejon të shtoni, fshini ose ndryshoni krejt elementët, sipas dëshirës.</string>
|
||||||
<string name="html_text_dev_feature_encourage">po i nxisni zhvilluesit të krijojnë <strong>veçori të reja</strong> dhe të <strong>ndreqin të meta</strong> në përputhje me sugjerimet tuaja.</string>
|
<string name="html_text_dev_feature_encourage">po i nxisni zhvilluesit të krijojnë <strong>veçori të reja</strong> dhe të <strong>ndreqin të meta</strong> në përputhje me sugjerimet tuaja.</string>
|
||||||
<string name="warning_large_keyfile">Nuk rekomandohet të shtohet një kartelë kyç e madhe, kjo mund të pengojë hapjen e bazës së të dhënave.</string>
|
<string name="warning_large_keyfile">Nuk rekomandohet të shtohet një kartelë kyç e madhe, kjo mund të pengojë hapjen e bazës së të dhënave.</string>
|
||||||
<string name="education_entry_edit_summary">Përpunojeni zërin tuaj me fusha vetjake. Pool data can be referenced between different entry fields.</string>
|
<string name="education_entry_edit_summary">Përpunojeni zërin tuaj me fusha vetjake. Pool data can be referenced between different entry fields.</string>
|
||||||
<string name="error_otp_type">Lloji OTP ekzistues s’njihet nga ky formular, vlerësimi i tij mund të mos prodhojë më saktë token-in.</string>
|
<string name="error_otp_type">Lloji OTP ekzistues s’njihet nga ky formular dhe vlerësimi i tij mund të mos prodhojë më saktë token-in.</string>
|
||||||
<string name="warning_database_read_only">Akordo hyrje për shkrim kartelash, që të ruhen ndryshimet e bazës së të dhënave</string>
|
<string name="warning_database_read_only">Akordo hyrje për shkrim kartelash, që të ruhen ndryshimet e bazës së të dhënave</string>
|
||||||
<string name="warning_database_info_changed_options">Përzieni të dhënat, mbishkruani ndryshimet që nga jashtë duke e ruajtur bazën e të dhënave, ose duke e ringarkuar me ndryshimet më të reja.</string>
|
<string name="warning_database_info_changed_options">Përzieni të dhënat, mbishkruani ndryshimet që nga jashtë duke e ruajtur bazën e të dhënave, ose duke e ringarkuar me ndryshimet më të reja.</string>
|
||||||
<string name="warning_database_revoked">Hyrja te kartela e shfuqizuar nga përgjegjësi i kartelave, mbylleni bazën e të dhënave dhe rihapeni që prej vendndodhjes së saj.</string>
|
<string name="warning_database_revoked">Hyrja te kartela e shfuqizuar nga përgjegjësi i kartelave, mbylleni bazën e të dhënave dhe rihapeni që prej vendndodhjes së saj.</string>
|
||||||
|
|||||||
@@ -433,6 +433,32 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the real parent in database from a group defined as parent
|
||||||
|
* If the parent is null, simply return the root group
|
||||||
|
* Guaranteed that a return group is linked to the database tree through its ancestors
|
||||||
|
*/
|
||||||
|
private fun getAttachedParent(
|
||||||
|
group: GroupKDBX?
|
||||||
|
): GroupKDBX {
|
||||||
|
var realParent: GroupKDBX = database.rootGroup!!
|
||||||
|
group?.let { parent ->
|
||||||
|
val parentInDatabase = database.getGroupById(parent.nodeId)
|
||||||
|
if (parentInDatabase == null) {
|
||||||
|
realParent = GroupKDBX().apply {
|
||||||
|
updateWith(parent, updateParents = false)
|
||||||
|
}
|
||||||
|
database.addGroupTo(
|
||||||
|
realParent,
|
||||||
|
getAttachedParent(parent.parent)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
realParent = parentInDatabase
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return realParent
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to merge a KDBX entry
|
* Utility method to merge a KDBX entry
|
||||||
*/
|
*/
|
||||||
@@ -443,10 +469,7 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
|||||||
|
|
||||||
databaseToMerge.getEntryById(entryId)?.let { srcEntryToMerge ->
|
databaseToMerge.getEntryById(entryId)?.let { srcEntryToMerge ->
|
||||||
// Retrieve parent in current database
|
// Retrieve parent in current database
|
||||||
var parentEntryToMerge: GroupKDBX? = null
|
val parentEntryToMerge: GroupKDBX = getAttachedParent(srcEntryToMerge.parent)
|
||||||
srcEntryToMerge.parent?.nodeId?.let {
|
|
||||||
parentEntryToMerge = database.getGroupById(it)
|
|
||||||
}
|
|
||||||
val entryToMerge = EntryKDBX().apply {
|
val entryToMerge = EntryKDBX().apply {
|
||||||
updateWith(srcEntryToMerge, copyHistory = true, updateParents = false)
|
updateWith(srcEntryToMerge, copyHistory = true, updateParents = false)
|
||||||
}
|
}
|
||||||
@@ -478,8 +501,7 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
|||||||
// If it's a deleted object, but another instance was updated
|
// If it's a deleted object, but another instance was updated
|
||||||
// If entry parent to add exists and in current database
|
// If entry parent to add exists and in current database
|
||||||
if ((deletedObject == null
|
if ((deletedObject == null
|
||||||
|| deletedObject.deletionTime.isBefore(entryToMerge.lastModificationTime))
|
|| deletedObject.deletionTime.isBefore(entryToMerge.lastModificationTime))) {
|
||||||
&& parentEntryToMerge != null) {
|
|
||||||
database.addEntryTo(entryToMerge, parentEntryToMerge)
|
database.addEntryTo(entryToMerge, parentEntryToMerge)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -488,51 +510,46 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
|||||||
// Merge by modification time
|
// Merge by modification time
|
||||||
if (entry.lastModificationTime.isBefore(entryToMerge.lastModificationTime)) {
|
if (entry.lastModificationTime.isBefore(entryToMerge.lastModificationTime)) {
|
||||||
// Update entry with databaseEntryToMerge and merge history
|
// Update entry with databaseEntryToMerge and merge history
|
||||||
addHistory(entry, entryToMerge)
|
entryToMerge.addHistoryFrom(entry)
|
||||||
if (parentEntryToMerge == entry.parent) {
|
|
||||||
entry.updateWith(entryToMerge, copyHistory = true, updateParents = false)
|
entry.updateWith(entryToMerge, copyHistory = true, updateParents = false)
|
||||||
} else {
|
// Move the current entry to the verified location
|
||||||
database.removeEntryFrom(entry, entry.parent)
|
database.removeEntryFrom(entry, entry.parent)
|
||||||
if (parentEntryToMerge != null) {
|
database.addEntryTo(entry, parentEntryToMerge)
|
||||||
database.addEntryTo(entryToMerge, parentEntryToMerge)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (entry.lastModificationTime.isAfter(entryToMerge.lastModificationTime)) {
|
} else if (entry.lastModificationTime.isAfter(entryToMerge.lastModificationTime)) {
|
||||||
addHistory(entryToMerge, entry)
|
// Don't touch the location but update the entry history
|
||||||
|
entry.addHistoryFrom(entryToMerge)
|
||||||
} else if (entry.lastModificationTime.isEquals(entryToMerge.lastModificationTime)) {
|
} else if (entry.lastModificationTime.isEquals(entryToMerge.lastModificationTime)) {
|
||||||
// If it's the same modification time, simply move entry to the right location
|
// If it's the same modification time, simply move entry to the right location,
|
||||||
parentEntryToMerge?.let {
|
// Current entry and entry to merge are normally the same
|
||||||
database.removeEntryFrom(entry, entry.parent)
|
database.removeEntryFrom(entry, entry.parent)
|
||||||
database.addEntryTo(entryToMerge, parentEntryToMerge)
|
database.addEntryTo(entry, parentEntryToMerge)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to merge an history from an [entryA] to an [entryB],
|
* Utility method to merge an history from an [entryA]
|
||||||
* [entryB] is modified
|
|
||||||
*/
|
*/
|
||||||
private fun addHistory(entryA: EntryKDBX, entryB: EntryKDBX) {
|
private fun EntryKDBX.addHistoryFrom(entryA: EntryKDBX) {
|
||||||
// Keep entry as history if already not present
|
// Keep entry as history if already not present
|
||||||
entryA.history.forEach { history ->
|
entryA.history.forEach { history ->
|
||||||
// If history not present
|
// If history not present
|
||||||
if (!entryB.history.any {
|
if (!this.history.any {
|
||||||
it.lastModificationTime == history.lastModificationTime
|
it.lastModificationTime == history.lastModificationTime
|
||||||
}) {
|
}) {
|
||||||
entryB.addEntryToHistory(history)
|
this.addEntryToHistory(history)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Last entry not present
|
// Last entry not present
|
||||||
if (entryB.history.find {
|
if (this.history.find {
|
||||||
it.lastModificationTime == entryA.lastModificationTime
|
it.lastModificationTime == entryA.lastModificationTime
|
||||||
} == null) {
|
} == null) {
|
||||||
val history = EntryKDBX().apply {
|
val history = EntryKDBX().apply {
|
||||||
updateWith(entryA, copyHistory = false, updateParents = false)
|
updateWith(entryA, copyHistory = false, updateParents = false)
|
||||||
parent = null
|
parent = null
|
||||||
}
|
}
|
||||||
entryB.addEntryToHistory(history)
|
this.addEntryToHistory(history)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,10 +563,7 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
|||||||
|
|
||||||
databaseToMerge.getGroupById(groupId)?.let { srcGroupToMerge ->
|
databaseToMerge.getGroupById(groupId)?.let { srcGroupToMerge ->
|
||||||
// Retrieve parent in current database
|
// Retrieve parent in current database
|
||||||
var parentGroupToMerge: GroupKDBX? = null
|
val parentGroupToMerge: GroupKDBX = getAttachedParent(srcGroupToMerge.parent)
|
||||||
srcGroupToMerge.parent?.nodeId?.let {
|
|
||||||
parentGroupToMerge = database.getGroupById(it)
|
|
||||||
}
|
|
||||||
val groupToMerge = GroupKDBX().apply {
|
val groupToMerge = GroupKDBX().apply {
|
||||||
updateWith(srcGroupToMerge, updateParents = false)
|
updateWith(srcGroupToMerge, updateParents = false)
|
||||||
}
|
}
|
||||||
@@ -557,8 +571,7 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
|||||||
if (group == null) {
|
if (group == null) {
|
||||||
// If group parent to add exists and in current database
|
// If group parent to add exists and in current database
|
||||||
if ((deletedObject == null
|
if ((deletedObject == null
|
||||||
|| deletedObject.deletionTime.isBefore(groupToMerge.lastModificationTime))
|
|| deletedObject.deletionTime.isBefore(groupToMerge.lastModificationTime))) {
|
||||||
&& parentGroupToMerge != null) {
|
|
||||||
database.addGroupTo(groupToMerge, parentGroupToMerge)
|
database.addGroupTo(groupToMerge, parentGroupToMerge)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -566,20 +579,16 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
|||||||
mergeCustomData(group.customData, groupToMerge.customData)
|
mergeCustomData(group.customData, groupToMerge.customData)
|
||||||
// Merge by modification time
|
// Merge by modification time
|
||||||
if (group.lastModificationTime.isBefore(groupToMerge.lastModificationTime)) {
|
if (group.lastModificationTime.isBefore(groupToMerge.lastModificationTime)) {
|
||||||
if (parentGroupToMerge == group.parent) {
|
group.updateWith(groupToMerge, updateParents = false)
|
||||||
group.updateWith(groupToMerge, false)
|
// Update the current group location to the verified one
|
||||||
} else {
|
|
||||||
database.removeGroupFrom(group, group.parent)
|
database.removeGroupFrom(group, group.parent)
|
||||||
if (parentGroupToMerge != null) {
|
database.addGroupTo(group, parentGroupToMerge)
|
||||||
database.addGroupTo(groupToMerge, parentGroupToMerge)
|
} else if (group.lastModificationTime.isAfter(group.lastModificationTime)) {
|
||||||
}
|
// Don't touch the location
|
||||||
}
|
|
||||||
} else if (group.lastModificationTime.isEquals(groupToMerge.lastModificationTime)) {
|
} else if (group.lastModificationTime.isEquals(groupToMerge.lastModificationTime)) {
|
||||||
// If it's the same modification time, simply move group to the right location
|
// If it's the same modification time, simply move group to the right location
|
||||||
parentGroupToMerge?.let {
|
|
||||||
database.removeGroupFrom(group, group.parent)
|
database.removeGroupFrom(group, group.parent)
|
||||||
database.addGroupTo(groupToMerge, parentGroupToMerge)
|
database.addGroupTo(group, parentGroupToMerge)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,5 +159,7 @@ object AppOriginEntryField {
|
|||||||
*/
|
*/
|
||||||
fun Field.isWebDomain(): Boolean {
|
fun Field.isWebDomain(): Boolean {
|
||||||
return this.name.startsWith(WEB_DOMAIN_FIELD_NAME)
|
return this.name.startsWith(WEB_DOMAIN_FIELD_NAME)
|
||||||
|
|| this.name.contains("_$WEB_DOMAIN_FIELD_NAME")
|
||||||
|
|| this.name.contains("${WEB_DOMAIN_FIELD_NAME}_")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1 +1 @@
|
|||||||
KeePassDX مدير كلمات سر مفتوح المصدر
|
KeePassDX
|
||||||
|
|||||||
4
fastlane/metadata/android/en-US/changelogs/147.txt
Normal file
4
fastlane/metadata/android/en-US/changelogs/147.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
* Fix database merge algorithm #2223
|
||||||
|
* Fix save search info #2243
|
||||||
|
* Fix Play Service as privileged app for Passkey Cross Device Authentication #2244
|
||||||
|
* Small fixes
|
||||||
@@ -1 +1 @@
|
|||||||
KeePassDX - Contraseñas FOSS
|
KeePassDX Pass(key/word) Vault
|
||||||
|
|||||||
4
fastlane/metadata/android/fr-FR/changelogs/147.txt
Normal file
4
fastlane/metadata/android/fr-FR/changelogs/147.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
* Correction de l'algorithme de fusion des bases de données #2223
|
||||||
|
* Correction de la sauvegarde des infos de recherche #2243
|
||||||
|
* Correction Play Service comme appli privilégiée pour l'authentification Passkey multi-appareils #2244
|
||||||
|
* Small fixes
|
||||||
@@ -1 +1 @@
|
|||||||
KeePassDX – FOSS trezor za lozinke
|
KeePassDX Pass(key/word) Vault
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
KeePassDX – Pengaman Sandi FOSS
|
KeePassDX Pass(key/word) Vault
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
Cassaforte di pass(key/word) KeePassDX
|
KeePassDX Pass(key/word) Vault
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
KeePassDX - Безбедносен софтвер за лозинки и е слободен софтвер
|
KeePassDX Pass(key/word) Vault
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
KeePassDX - менеджер паролей/ключей
|
KeePassDX - менеджер паролей
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
KeePassDX - Parola/Anahtar Kasası
|
KeePassDX Pass(key/word) Vault
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
KeePassDX - FOSS 密碼管理器
|
KeePassDX Pass(key/word) Vault
|
||||||
|
|||||||
Reference in New Issue
Block a user