Public Access
101 lines
5.8 KiB
XML
101 lines
5.8 KiB
XML
<UserControl xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:vm="using:DodoSSH.Client.Shell.ViewModels"
|
|
x:Class="DodoSSH.Client.App.Views.UnlockCard"
|
|
x:DataType="vm:MainWindowViewModel">
|
|
|
|
<!--
|
|
The unlock screen's contents.
|
|
|
|
Extracted from MainWindow.axaml so that it can be laid out and looked at: MainWindow cannot be shown in
|
|
the headless session at all — WebView2's adapter refuses its thread, which LayoutHarnessTests pins — so
|
|
markup that stays inside that file is markup no test can measure. This card is the one on the screen
|
|
with the least room to spare and the most conditional content: a disclosure about shells left running,
|
|
and a way out for a forgotten passphrase, both of which appear underneath a form that already fills most
|
|
of the height the window guarantees.
|
|
|
|
A bare StackPanel rather than a card, because the card is the frame MainWindow puts around it.
|
|
-->
|
|
|
|
<StackPanel Spacing="12">
|
|
|
|
<TextBlock Classes="heading" Text="Unlock your keychain" />
|
|
<TextBlock Text="{Binding AccountName}" Foreground="{StaticResource Info}" />
|
|
|
|
<!--
|
|
Named because locking has to put the keyboard here explicitly, and reached from the window through
|
|
PassphraseBox. The terminal's native child window keeps Win32 focus when it is collapsed, so without
|
|
that this box would show a caret and silently swallow the passphrase — see NativeKeyboardFocus.
|
|
|
|
Enter unlocks. A KeyBinding on the box rather than a handler on the window, because this is a property
|
|
of the control the passphrase is typed into and not of the shell's state: the keyboard is put here on
|
|
every lock, so the one gesture everybody makes after typing a password reaches the command this box
|
|
exists for. A single-line TextBox does not handle Enter itself, so nothing is being fought over.
|
|
-->
|
|
<TextBox x:Name="UnlockPassphrase" Text="{Binding Passphrase}"
|
|
PlaceholderText="keychain passphrase" PasswordChar="•">
|
|
<TextBox.KeyBindings>
|
|
<KeyBinding Gesture="Enter" Command="{Binding UnlockCommand}" />
|
|
</TextBox.KeyBindings>
|
|
</TextBox>
|
|
|
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
<Button Classes="accent" Content="UNLOCK" Command="{Binding UnlockCommand}"
|
|
IsEnabled="{Binding !IsBusy}" />
|
|
<!--
|
|
Shown only when this machine has both a registered wrap and a keystore still willing to release the
|
|
key. Absent rather than disabled, because a greyed-out "Use Touch ID" on a machine that never
|
|
had it invites the reading that something is broken — and the passphrase box beside it is not a
|
|
fallback, it is the ordinary way in.
|
|
-->
|
|
<Button Classes="ghost" Content="{Binding DeviceUnlock.Button}"
|
|
Command="{Binding UnlockWithDeviceCommand}"
|
|
IsEnabled="{Binding !IsBusy}"
|
|
IsVisible="{Binding CanUnlockWithDevice}"
|
|
ToolTip.Tip="{Binding DeviceUnlock.Tip}" />
|
|
</StackPanel>
|
|
|
|
<TextBlock Classes="hint" Text="{Binding StatusMessage}" TextWrapping="Wrap" />
|
|
<TextBlock Classes="hint" FontSize="12" TextWrapping="Wrap"
|
|
Text="This works with no network: the salt and the wrapped key are already on this machine." />
|
|
|
|
<!--
|
|
Stated here because the lock screen is what hides it. The terminal's WebView is collapsed while
|
|
locked, so a shell left running is invisible as well as unstopped — and a screen saying "Unlock your
|
|
vault" over a machine that still holds authenticated SSH channels is exactly the kind of half-truth
|
|
this project writes down instead of implying. Visible only when there is something to disclose, so an
|
|
ordinary launch stays quiet.
|
|
-->
|
|
<Border Background="{StaticResource Panel}" BorderBrush="{StaticResource Border}"
|
|
BorderThickness="1" CornerRadius="4" Padding="10,8"
|
|
IsVisible="{Binding HasLiveSessions, FallbackValue=False}">
|
|
<StackPanel Spacing="4">
|
|
<!-- Live, not Info: this counts shells that are still running, which is the fact the host list,
|
|
the tab strip and the phone's own lock screen all paint green. -->
|
|
<TextBlock Text="{Binding LiveSessionSummary}" Foreground="{StaticResource Live}"
|
|
FontWeight="SemiBold" TextWrapping="Wrap" />
|
|
<TextBlock Classes="hint" FontSize="12" TextWrapping="Wrap"
|
|
Text="Locking closes the keychain, not your terminals: a job you started keeps running, and its output is waiting behind this screen. It also means this machine still holds an open, authenticated channel to those hosts — locked describes the keychain, not the connections. Quit DodoSSH to end them." />
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!--
|
|
The way out of a forgotten passphrase, and the only one there is. Nothing can recover a passphrase —
|
|
there is no server-side reset by design — so the honest offer is to reset this machine and sign in
|
|
again, which costs whatever this machine had not yet pushed and nothing else. Stated here rather than
|
|
left to be discovered, because somebody stuck on this screen has no other route and quitting the
|
|
application does not help.
|
|
-->
|
|
<Border Height="1" Background="{StaticResource BorderSubtle}" />
|
|
|
|
<StackPanel Spacing="6">
|
|
<TextBlock Classes="hint" FontSize="12" TextWrapping="Wrap"
|
|
Text="Forgotten your passphrase? Nothing can recover it — not even whoever runs the server. What you can do is reset this machine and sign in again; the keychain is on the server and comes back." />
|
|
<Button Classes="ghost" Content="RESET THIS MACHINE"
|
|
Command="{Binding SignOutCommand}" HorizontalAlignment="Left" />
|
|
</StackPanel>
|
|
|
|
</StackPanel>
|
|
|
|
</UserControl>
|