Public Access
Desktop: let a lock pressed during an unlock win, instead of the unlock finishing behind it
This commit is contained in:
1 parent
37e9d74938
commit
079a273d46
3 files changed
+99
-6
No files matched your search
@@ -639,6 +639,36 @@ public sealed partial class ShellFlowTests : IAsyncLifetime
|
||||
server.LiveRowCount.ShouldBe(1, "a save should reach the server without pressing Sync");
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Lock pressed while an unlock is still loading. The unlock is held at the point the vault has been handed
|
||||
/// over and is about to be read — the device-key probe — and the lock lands there. The unlock used to carry
|
||||
/// on regardless, into a vault the lock had disposed and a shell that no longer held one, and put an
|
||||
/// exception's message on the lock screen. An earlier lock, before the hand-over, would have left the vault
|
||||
/// opening behind the lock screen; both are the same check.
|
||||
/// </remarks>
|
||||
[Fact]
|
||||
public async Task LockingWhileAnUnlockIsStillLoading_LeavesItLocked()
|
||||
{
|
||||
await EnrolledAndConfirmedAsync();
|
||||
|
||||
var release = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
deviceKeys.HoldAvailability = release.Task;
|
||||
|
||||
shell.Passphrase = Passphrase;
|
||||
var unlocking = shell.UnlockCommand.ExecuteAsync(null);
|
||||
|
||||
await EventuallyAsync(() => shell.Vault is not null, "the unlock should reach the hand-over and wait there");
|
||||
|
||||
await shell.LockCommand.ExecuteAsync(null);
|
||||
|
||||
release.SetResult();
|
||||
await unlocking;
|
||||
|
||||
shell.State.ShouldBe(ShellState.Locked);
|
||||
shell.Vault.ShouldBeNull();
|
||||
shell.StatusMessage.ShouldBe("Locked.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AnAutomaticPass_SaysNothingWhenThereIsNothingToDo()
|
||||
{
|
||||
|
||||
@@ -25,8 +25,18 @@ internal sealed class FakeDeviceKeyStore : IDeviceKeyStore
|
||||
internal void Overwrite(byte[] replacement) => key = replacement;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ValueTask<bool> IsAvailableAsync(CancellationToken cancellationToken) =>
|
||||
ValueTask.FromResult(IsAvailable);
|
||||
public async ValueTask<bool> IsAvailableAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (HoldAvailability is { } hold)
|
||||
{
|
||||
await hold.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return IsAvailable;
|
||||
}
|
||||
|
||||
/// <summary>When set, availability is not answered until it completes: an unlock held part-way.</summary>
|
||||
internal Task? HoldAvailability { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ValueTask SaveAsync(ReadOnlyMemory<byte> devicePrivateKey, CancellationToken cancellationToken)
|
||||
|
||||
Reference in new issue
Block a user