Skip to content

Commit

Permalink
Merge branch 'release/2.5beta29'
Browse files Browse the repository at this point in the history
  • Loading branch information
J-Jamet committed Mar 25, 2020
2 parents a846ec2 + 4c16303 commit 9fc5e67
Show file tree
Hide file tree
Showing 112 changed files with 2,503 additions and 1,152 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
KeePassDX(2.5beta29)
* Upgrade autofill algorithm
* Delete registered KeyFile after save new credentials
* Fix title and username entry view refresh after an update
* Fix database lock request (open notification always active)
* Allow empty title in entries
* Add expiration datetime

KeePassDX(2.5beta28)
* Fix read only database
* Upgrade to Android SDK 29
Expand Down
2 changes: 1 addition & 1 deletion ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ KeePassDX is a **free open source password manager for Android**, which helps yo

Yes, KeePassDX is under **free license (OSI certified)** and **without advertising**. You can have a look at its full source and check whether the encryption algorithms are implemented correctly.

*Note : If you access the application from a store, visual features may not be available to incentivize the contribution to the work of open source projects. These optional visuals are accessible after a donation (and a small congratulation message :) or the purchase of an extended version, but do not worry, the main features remain completely free. If you contribute to the project and you do not have access to the themes, do not hesitate to contact me at [[email protected]]([email protected]), I will give you the procedure.*
*Note : If you access the application from a store, visual styles may not be available to encourage contribution to the work of open source projects. These optional styles are accessible after a contribution (and a congratulation message :) or the purchase of an extended version, but do not worry, the main features remain completely free. If you contribute to the project and you do not have access to the themes, do not hesitate to contact me at [[email protected]]([email protected]), I will give you the procedure.*

## Contributions

Expand Down
6 changes: 3 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ android {
applicationId "com.kunzisoft.keepass"
minSdkVersion 14
targetSdkVersion 29
versionCode = 28
versionName = "2.5beta28"
versionCode = 29
versionName = "2.5beta29"
multiDexEnabled true

testApplicationId = "com.kunzisoft.keepass.tests"
Expand Down Expand Up @@ -86,7 +86,7 @@ android {
}

def spongycastleVersion = "1.58.0.0"
def room_version = "2.2.4"
def room_version = "2.2.5"

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -541,12 +541,10 @@ class EntryActivity : LockingActivity() {

override fun finish() {
// Transit data in previous Activity after an update
/*
TODO Slowdown when add entry as result
Intent intent = new Intent();
intent.putExtra(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY, mEntry);
onFinish(EntryEditActivity.UPDATE_ENTRY_RESULT_CODE, intent);
*/
Intent().apply {
putExtra(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY, mEntry)
setResult(EntryEditActivity.UPDATE_ENTRY_RESULT_CODE, this)
}
super.finish()
}

Expand Down
170 changes: 139 additions & 31 deletions app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,24 @@
package com.kunzisoft.keepass.activities

import android.app.Activity
import android.app.DatePickerDialog
import android.app.TimePickerDialog
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.ScrollView
import android.widget.DatePicker
import android.widget.TimePicker
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.ActionMenuView
import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.widget.NestedScrollView
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.GeneratePasswordDialogFragment
import com.kunzisoft.keepass.activities.dialogs.IconPickerDialogFragment
import com.kunzisoft.keepass.activities.dialogs.SetOTPDialogFragment
import com.kunzisoft.keepass.activities.dialogs.*
import com.kunzisoft.keepass.activities.lock.LockingActivity
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.DateInstant
Expand All @@ -52,12 +56,15 @@ import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.MenuUtil
import com.kunzisoft.keepass.view.EntryEditContentsView
import com.kunzisoft.keepass.view.showActionError
import org.joda.time.DateTime
import java.util.*

class EntryEditActivity : LockingActivity(),
IconPickerDialogFragment.IconPickerListener,
GeneratePasswordDialogFragment.GeneratePasswordListener,
SetOTPDialogFragment.CreateOtpListener {
SetOTPDialogFragment.CreateOtpListener,
DatePickerDialog.OnDateSetListener,
TimePickerDialog.OnTimeSetListener {

private var mDatabase: Database? = null

Expand All @@ -70,8 +77,9 @@ class EntryEditActivity : LockingActivity(),

// Views
private var coordinatorLayout: CoordinatorLayout? = null
private var scrollView: ScrollView? = null
private var scrollView: NestedScrollView? = null
private var entryEditContentsView: EntryEditContentsView? = null
private var entryEditAddToolBar: ActionMenuView? = null
private var saveView: View? = null

// Education
Expand All @@ -94,6 +102,16 @@ class EntryEditActivity : LockingActivity(),

entryEditContentsView = findViewById(R.id.entry_edit_contents)
entryEditContentsView?.applyFontVisibilityToFields(PreferencesUtil.fieldFontIsInVisibility(this))
entryEditContentsView?.onDateClickListener = View.OnClickListener {
entryEditContentsView?.expiresDate?.date?.let { expiresDate ->
val dateTime = DateTime(expiresDate)
val defaultYear = dateTime.year
val defaultMonth = dateTime.monthOfYear-1
val defaultDay = dateTime.dayOfMonth
DatePickerFragment.getInstance(defaultYear, defaultMonth, defaultDay)
.show(supportFragmentManager, "DatePickerFragment")
}
}
// Focus view to reinitialize timeout
resetAppTimeoutWhenViewFocusedOrChanged(entryEditContentsView)

Expand Down Expand Up @@ -167,17 +185,46 @@ class EntryEditActivity : LockingActivity(),
// Add listener to the icon
entryEditContentsView?.setOnIconViewClickListener { IconPickerDialogFragment.launch(this@EntryEditActivity) }

// Generate password button
entryEditContentsView?.setOnPasswordGeneratorClickListener { openPasswordGenerator() }
// Bottom Bar
entryEditAddToolBar = findViewById(R.id.entry_edit_bottom_bar)
entryEditAddToolBar?.apply {
menuInflater.inflate(R.menu.entry_edit, menu)

// Save button
saveView = findViewById(R.id.entry_edit_save)
saveView?.setOnClickListener { saveEntry() }
menu.findItem(R.id.menu_add_field).apply {
val allowCustomField = mNewEntry?.allowCustomFields() == true
isEnabled = allowCustomField
isVisible = allowCustomField
}

entryEditContentsView?.allowCustomField(mNewEntry?.allowCustomFields() == true) {
addNewCustomField()
menu.findItem(R.id.menu_add_otp).apply {
val allowOTP = mDatabase?.allowOTP == true
isEnabled = allowOTP
isVisible = allowOTP
}

setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.menu_generate_password -> {
openPasswordGenerator()
true
}
R.id.menu_add_field -> {
addNewCustomField()
true
}
R.id.menu_add_otp -> {
setupOTP()
true
}
else -> true
}
}
}

// Save button
saveView = findViewById(R.id.entry_edit_validate)
saveView?.setOnClickListener { saveEntry() }

// Verify the education views
entryEditActivityEducation = EntryEditActivityEducation(this)

Expand Down Expand Up @@ -207,6 +254,9 @@ class EntryEditActivity : LockingActivity(),
username = if (newEntry.username.isEmpty()) mDatabase?.defaultUsername ?:"" else newEntry.username
url = newEntry.url
password = newEntry.password
expires = newEntry.expires
if (expires)
expiresDate = newEntry.expiryTime
notes = newEntry.notes
for (entry in newEntry.customFields.entries) {
post {
Expand All @@ -228,7 +278,11 @@ class EntryEditActivity : LockingActivity(),
username = entryView.username
url = entryView.url
password = entryView.password
notes = entryView.notes
expires = entryView.expires
if (entryView.expires) {
expiryTime = entryView.expiresDate
}
notes = entryView. notes
entryView.customFields.forEach { customField ->
putExtraField(customField.name, customField.protectedValue)
}
Expand Down Expand Up @@ -259,6 +313,13 @@ class EntryEditActivity : LockingActivity(),
entryEditContentsView?.addEmptyCustomField()
}

private fun setupOTP() {
// Retrieve the current otpElement if exists
// and open the dialog to set up the OTP
SetOTPDialogFragment.build(mEntry?.getOtpElement()?.otpModel)
.show(supportFragmentManager, "addOTPDialog")
}

/**
* Saves the new entry or update an existing entry in the database
*/
Expand Down Expand Up @@ -307,8 +368,6 @@ class EntryEditActivity : LockingActivity(),
// Save database not needed here
menu.findItem(R.id.menu_save_database)?.isVisible = false
MenuUtil.contributionMenuInflater(inflater, menu)
if (mDatabase?.allowOTP == true)
inflater.inflate(R.menu.entry_otp, menu)

entryEditActivityEducation?.let {
Handler().post { performedNextEducation(it) }
Expand All @@ -318,12 +377,10 @@ class EntryEditActivity : LockingActivity(),
}

private fun performedNextEducation(entryEditActivityEducation: EntryEditActivityEducation) {
val passwordView = entryEditContentsView?.generatePasswordView
val addNewFieldView = entryEditContentsView?.addNewFieldButton

val generatePasswordEducationPerformed = passwordView != null
val passwordGeneratorView: View? = entryEditAddToolBar?.findViewById(R.id.menu_generate_password)
val generatePasswordEducationPerformed = passwordGeneratorView != null
&& entryEditActivityEducation.checkAndPerformedGeneratePasswordEducation(
passwordView,
passwordGeneratorView,
{
openPasswordGenerator()
},
Expand All @@ -332,14 +389,28 @@ class EntryEditActivity : LockingActivity(),
}
)
if (!generatePasswordEducationPerformed) {
// entryNewFieldEducationPerformed
mNewEntry != null && mNewEntry!!.allowCustomFields() && mNewEntry!!.customFields.isEmpty()
val addNewFieldView: View? = entryEditAddToolBar?.findViewById(R.id.menu_add_field)
val addNewFieldEducationPerformed = mNewEntry != null
&& mNewEntry!!.allowCustomFields() && mNewEntry!!.customFields.isEmpty()
&& addNewFieldView != null && addNewFieldView.visibility == View.VISIBLE
&& entryEditActivityEducation.checkAndPerformedEntryNewFieldEducation(
addNewFieldView,
{
addNewCustomField()
})
},
{
performedNextEducation(entryEditActivityEducation)
}
)
if (!addNewFieldEducationPerformed) {
val setupOtpView: View? = entryEditAddToolBar?.findViewById(R.id.menu_add_otp)
setupOtpView != null && setupOtpView.visibility == View.VISIBLE
&& entryEditActivityEducation.checkAndPerformedSetUpOTPEducation(
setupOtpView,
{
setupOTP()
})
}
}
}

Expand All @@ -356,14 +427,9 @@ class EntryEditActivity : LockingActivity(),
MenuUtil.onContributionItemSelected(this)
return true
}
R.id.menu_add_otp -> {
// Retrieve the current otpElement if exists
// and open the dialog to set up the OTP
SetOTPDialogFragment.build(mEntry?.getOtpElement()?.otpModel)
.show(supportFragmentManager, "addOTPDialog")
return true
android.R.id.home -> {
onBackPressed()
}
android.R.id.home -> finish()
}

return super.onOptionsItemSelected(item)
Expand All @@ -383,6 +449,39 @@ class EntryEditActivity : LockingActivity(),
}
}

override fun onDateSet(datePicker: DatePicker?, year: Int, month: Int, day: Int) {
// To fix android 4.4 issue
// https://stackoverflow.com/questions/12436073/datepicker-ondatechangedlistener-called-twice
if (datePicker?.isShown == true) {
entryEditContentsView?.expiresDate?.date?.let { expiresDate ->
// Save the date
entryEditContentsView?.expiresDate =
DateInstant(DateTime(expiresDate)
.withYear(year)
.withMonthOfYear(month + 1)
.withDayOfMonth(day)
.toDate())
// Launch the time picker
val dateTime = DateTime(expiresDate)
val defaultHour = dateTime.hourOfDay
val defaultMinute = dateTime.minuteOfHour
TimePickerFragment.getInstance(defaultHour, defaultMinute)
.show(supportFragmentManager, "TimePickerFragment")
}
}
}

override fun onTimeSet(timePicker: TimePicker?, hours: Int, minutes: Int) {
entryEditContentsView?.expiresDate?.date?.let { expiresDate ->
// Save the date
entryEditContentsView?.expiresDate =
DateInstant(DateTime(expiresDate)
.withHourOfDay(hours)
.withMinuteOfHour(minutes)
.toDate())
}
}

override fun onSaveInstanceState(outState: Bundle) {
mNewEntry?.let {
populateEntryWithViews(it)
Expand All @@ -406,6 +505,15 @@ class EntryEditActivity : LockingActivity(),
// Do nothing here
}

override fun onBackPressed() {
AlertDialog.Builder(this)
.setMessage(R.string.discard_changes)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok) { _, _ ->
super@EntryEditActivity.onBackPressed()
}.create().show()
}

override fun finish() {
// Assign entry callback as a result in all case
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,6 @@ class FileDatabaseSelectActivity : StylishActivity(),
onActionFinish = { actionTask, _ ->
when (actionTask) {
ACTION_DATABASE_CREATE_TASK -> {
// TODO Check
// mAdapterDatabaseHistory?.notifyDataSetChanged()
// updateFileListVisibility()
GroupActivity.launch(this@FileDatabaseSelectActivity)
}
}
Expand Down
Loading

0 comments on commit 9fc5e67

Please sign in to comment.