Files
DodoSSH/src/DodoSSH.Client.Shell/ViewModels/DeviceUnlockWording.cs
T

86 lines
3.9 KiB
C#

namespace DodoSSH.Client.Shell.ViewModels;
/// <summary>
/// What unlocking with this machine's device key is called here, and what it asks the person for.
/// </summary>
/// <remarks>
/// <para>
/// The words used to be Windows's everywhere: "USE WINDOWS HELLO" on a Mac, "Waiting for Windows…" over a
/// Linux PIN prompt, and a settings row that told a MacBook it needed a TPM. Each desktop has its own device
/// key store with its own gesture — see <c>WindowsDeviceKeyStore</c>, <c>MacDeviceKeyStore</c> and
/// <c>LinuxDeviceKeyStore</c> — and a button has to name the one the person is about to be shown, or it reads
/// as a feature for some other machine.
/// </para>
/// <para>
/// One record rather than a property per sentence on the shell, so that the five places these words appear
/// cannot disagree about which platform they are on.
/// </para>
/// </remarks>
/// <param name="Name">What the feature is called, as a settings row's title.</param>
/// <param name="Button">The unlock card's button, in the capitals every button here uses.</param>
/// <param name="Wait">The status line while the platform's prompt is up.</param>
/// <param name="Gesture">What opens the keychain instead of the passphrase, to finish a sentence.</param>
/// <param name="Keeper">What holds the key, to finish "Registered · …".</param>
/// <param name="Needs">What a machine with no device key store lacks, as a sentence of its own.</param>
internal sealed record DeviceUnlockWording(
string Name,
string Button,
string Wait,
string Gesture,
string Keeper,
string Needs)
{
internal static DeviceUnlockWording Windows { get; } = new(
"Windows Hello on this machine",
"USE WINDOWS HELLO",
"Waiting for Windows…",
"a Windows confirmation",
"the TPM holds a device key",
"That needs a TPM and a Windows keystore willing to release the key.");
internal static DeviceUnlockWording Mac { get; } = new(
"Touch ID on this Mac",
"USE TOUCH ID",
"Waiting for Touch ID…",
"Touch ID or your login password",
"the Secure Enclave holds a device key",
"That needs a Mac with a Secure Enclave and a login password set.");
internal static DeviceUnlockWording Linux { get; } = new(
"A device PIN on this machine",
"USE DEVICE PIN",
"Waiting for your PIN…",
"a PIN the TPM checks",
"the TPM holds a device key",
"That needs a TPM 2.0 this account is allowed to use.");
internal static DeviceUnlockWording Android { get; } = new(
"Fingerprint unlock on this phone",
"USE FINGERPRINT",
"Waiting for your fingerprint…",
"your fingerprint",
"the phone's keystore holds a device key",
"That needs a screen lock and a keystore willing to release the key.");
/// <summary>The wording for the platform this process is running on.</summary>
internal static DeviceUnlockWording ForThisPlatform { get; } =
OperatingSystem.IsAndroid() ? Android
: OperatingSystem.IsMacOS() ? Mac
: OperatingSystem.IsLinux() ? Linux
: Windows;
/// <summary>The settings caption for a machine that can register.</summary>
internal string Offer =>
$"Registers this machine so a later launch can open the keychain with {Gesture} instead of your passphrase. Your passphrase keeps working.";
/// <summary>The settings caption for a machine that has.</summary>
internal string Registered => $"Registered · {Keeper} that can open the keychain with {Gesture}.";
/// <summary>The settings caption for a machine that cannot.</summary>
internal string Unavailable =>
$"This machine has nowhere to keep a device key, so the keychain will keep asking for your passphrase. {Needs}";
/// <summary>The unlock button's tooltip.</summary>
internal string Tip => $"Opens the keychain with this machine's device key, after {Gesture}.";
}