mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-11-22 16:32:01 +03:00
Merge PR #1054.
This commit is contained in:
commit
baba514617
9
NEWS
9
NEWS
@ -1,3 +1,12 @@
|
||||
* Version 6.2.0 (released 2023-04-19)
|
||||
** Add support for custom account icons.
|
||||
** Desktop: Add systray icon for quick access to pinned accounts.
|
||||
** Win/Mac: Remember window position between launches.
|
||||
** UI: Swap click-area for OATH accounts (click on code button to open single-account view, double-click on account to copy code).
|
||||
** Android: Better support for large screens (landscape, multi-window).
|
||||
** Desktop: Fix issues with keyboard shortcuts sometimes not working and add new shortcuts.
|
||||
** Accessibility: Screen reader improvement for various parts of the UI.
|
||||
|
||||
* Version 6.1.1 (released 2023-02-13)
|
||||
** Android: Fix issues on Chromebooks when adding accounts.
|
||||
** Android: Fix to a bug when accounts might disappear from the account list when switching between apps with a YubiKey connected over USB.
|
||||
|
@ -63,6 +63,7 @@ import kotlinx.coroutines.*
|
||||
import kotlinx.serialization.encodeToString
|
||||
import java.net.URI
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
typealias OathAction = (Result<YubiKitOathSession, Exception>) -> Unit
|
||||
@ -100,6 +101,7 @@ class OathManager(
|
||||
@TargetApi(Build.VERSION_CODES.M)
|
||||
private fun createKeyStoreProviderM(): KeyProvider = KeyStoreProvider()
|
||||
|
||||
private val unlockOnConnect = AtomicBoolean(true)
|
||||
private var pendingAction: OathAction? = null
|
||||
private var refreshJob: Job? = null
|
||||
private var addToAny = false
|
||||
@ -241,8 +243,7 @@ class OathManager(
|
||||
override suspend fun processYubiKey(device: YubiKeyDevice) {
|
||||
try {
|
||||
device.withConnection<SmartCardConnection, Unit> { connection ->
|
||||
val session = YubiKitOathSession(connection)
|
||||
|
||||
val session = getOathSession(connection)
|
||||
val previousId = oathViewModel.sessionState.value?.deviceId
|
||||
if (session.deviceId == previousId && device is NfcYubiKeyDevice) {
|
||||
// Run any pending action
|
||||
@ -414,7 +415,7 @@ class OathManager(
|
||||
currentPassword: String?,
|
||||
newPassword: String,
|
||||
): String =
|
||||
useOathSession("Set password") { session ->
|
||||
useOathSession("Set password", unlock = false) { session ->
|
||||
if (session.isAccessKeySet) {
|
||||
if (currentPassword == null) {
|
||||
throw Exception("Must provide current password to be able to change it")
|
||||
@ -599,6 +600,29 @@ class OathManager(
|
||||
return false // the unlock did not work, session is locked
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a [YubiKitOathSession] for the [connection].
|
||||
* The session will be unlocked if [unlockOnConnect] is true.
|
||||
*
|
||||
* Generally we always want to try to unlock the session and that is why the variable
|
||||
* [unlockOnConnect] is also reset to true.
|
||||
*
|
||||
* Currently, only setPassword and unsetPassword will not unlock the session.
|
||||
*
|
||||
* @param connection the device SmartCard connection
|
||||
* @return a [YubiKitOathSession] which is unlocked or locked based on an internal parameter
|
||||
*/
|
||||
private fun getOathSession(connection: SmartCardConnection) : YubiKitOathSession {
|
||||
val session = YubiKitOathSession(connection)
|
||||
|
||||
if (!unlockOnConnect.compareAndSet(false, true)) {
|
||||
tryToUnlockOathSession(session)
|
||||
}
|
||||
|
||||
return session
|
||||
}
|
||||
|
||||
|
||||
private fun calculateOathCodes(session: YubiKitOathSession): Map<Credential, Code?> {
|
||||
val isUsbKey = appViewModel.connectedYubiKey.value != null
|
||||
var timestamp = System.currentTimeMillis()
|
||||
@ -626,37 +650,30 @@ class OathManager(
|
||||
unlock: Boolean = true,
|
||||
action: (YubiKitOathSession) -> T
|
||||
): T {
|
||||
|
||||
// callers can decide whether the session should be unlocked first
|
||||
unlockOnConnect.set(unlock)
|
||||
return appViewModel.connectedYubiKey.value?.let {
|
||||
useOathSessionUsb(it, unlock, action)
|
||||
} ?: useOathSessionNfc(title, unlock, action)
|
||||
useOathSessionUsb(it, action)
|
||||
} ?: useOathSessionNfc(title, action)
|
||||
}
|
||||
|
||||
private suspend fun <T> useOathSessionUsb(
|
||||
device: UsbYubiKeyDevice,
|
||||
unlock: Boolean = true,
|
||||
block: (YubiKitOathSession) -> T
|
||||
): T = device.withConnection<SmartCardConnection, T> {
|
||||
val session = YubiKitOathSession(it)
|
||||
if (unlock) {
|
||||
tryToUnlockOathSession(session)
|
||||
}
|
||||
block(session)
|
||||
block(getOathSession(it))
|
||||
}
|
||||
|
||||
private suspend fun <T> useOathSessionNfc(
|
||||
title: String,
|
||||
unlock: Boolean = true,
|
||||
block: (YubiKitOathSession) -> T
|
||||
): T {
|
||||
try {
|
||||
val result = suspendCoroutine { outer ->
|
||||
pendingAction = {
|
||||
outer.resumeWith(runCatching {
|
||||
val session = it.value
|
||||
if (unlock) {
|
||||
tryToUnlockOathSession(session)
|
||||
}
|
||||
block.invoke(session)
|
||||
block.invoke(it.value)
|
||||
})
|
||||
}
|
||||
dialogManager.showDialog(Icon.NFC, "Tap your key", title) {
|
||||
|
@ -6,8 +6,8 @@ VSVersionInfo(
|
||||
ffi=FixedFileInfo(
|
||||
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
|
||||
# Set not needed items to zero 0.
|
||||
filevers=(6, 1, 2, 0),
|
||||
prodvers=(6, 1, 2, 0),
|
||||
filevers=(6, 2, 1, 0),
|
||||
prodvers=(6, 2, 1, 0),
|
||||
# Contains a bitmask that specifies the valid bits 'flags'r
|
||||
mask=0x3f,
|
||||
# Contains a bitmask that specifies the Boolean attributes of the file.
|
||||
@ -31,11 +31,11 @@ VSVersionInfo(
|
||||
'040904b0',
|
||||
[StringStruct('CompanyName', 'Yubico'),
|
||||
StringStruct('FileDescription', 'Yubico Authenticator Helper'),
|
||||
StringStruct('FileVersion', '6.1.2-dev.0'),
|
||||
StringStruct('FileVersion', '6.2.1-dev.0'),
|
||||
StringStruct('LegalCopyright', 'Copyright (c) Yubico'),
|
||||
StringStruct('OriginalFilename', 'authenticator-helper.exe'),
|
||||
StringStruct('ProductName', 'Yubico Authenticator'),
|
||||
StringStruct('ProductVersion', '6.1.2-dev.0')])
|
||||
StringStruct('ProductVersion', '6.2.1-dev.0')])
|
||||
]),
|
||||
VarFileInfo([VarStruct('Translation', [1033, 1200])])
|
||||
]
|
||||
|
@ -1,5 +1,5 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// This file is generated by running ./set-version.py <version> <build>
|
||||
|
||||
const String version = '6.1.2-dev.0';
|
||||
const int build = 60102;
|
||||
const String version = '6.2.1-dev.0';
|
||||
const int build = 60201;
|
||||
|
@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
|
||||
# This field is updated by running ./set-version.py <version>
|
||||
# DO NOT MANUALLY EDIT THIS!
|
||||
version: 6.1.2-dev.0+60102
|
||||
version: 6.2.1-dev.0+60201
|
||||
|
||||
environment:
|
||||
sdk: '>=2.19.0 <3.0.0'
|
||||
|
@ -1,4 +1,4 @@
|
||||
$version="6.1.2-dev.0"
|
||||
$version="6.2.1-dev.0"
|
||||
|
||||
echo "Clean-up of old files"
|
||||
rm *.msi
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
|
||||
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
||||
<?define ProductVersion="6.1.2" ?>
|
||||
<?define ProductVersion="6.2.1" ?>
|
||||
<?define ProductName="Yubico Authenticator" ?>
|
||||
|
||||
<Product Id="*" UpgradeCode="fcbafc57-aaaa-47b8-b861-20bda48cd4f6" Name="$(var.ProductName)" Version="$(var.ProductVersion)" Manufacturer="Yubico AB" Language="1033">
|
||||
|
Loading…
Reference in New Issue
Block a user