1using CommunityToolkit.Mvvm.ComponentModel;
2using CommunityToolkit.Mvvm.Input;
3using CommunityToolkit.Mvvm.Messaging;
9using System.ComponentModel;
10using System.Globalization;
11using System.Reflection;
12using System.Security.Cryptography;
27 private const string allowed =
"Allowed";
28 private const string prohibited =
"Prohibited";
30 private readonly
bool initializing =
false;
38 this.initializing =
true;
41 this.CanProhibitScreenCapture =
ServiceRef.PlatformSpecific.CanProhibitScreenCapture;
42 this.ScreenCaptureMode = ServiceRef.PlatformSpecific.ProhibitScreenCapture ? prohibited : allowed;
44 this.CanUseFingerprint =
ServiceRef.PlatformSpecific.SupportsFingerprintAuthentication;
45 this.CanUseAlternativeAuthenticationMethods = this.CanUseFingerprint;
52 this.VersionNumber = AppInfo.VersionString;
53 this.BuildNumber = AppInfo.BuildString;
54 this.BuildTime = GetBuildTime();
55 this.DeviceManufactorer = DeviceInfo.Manufacturer.ToString();
56 this.DeviceModel = DeviceInfo.Model.ToString();
57 this.DevicePlatform = DeviceInfo.Platform.ToString();
58 this.DeviceVersion = DeviceInfo.Version.ToString();
62 this.initializing =
false;
76 await base.OnInitialize();
77 this.NotifyCommandsCanExecuteChanged();
83 return MainThread.InvokeOnMainThreadAsync(async () =>
85 await base.XmppService_ConnectionStateChanged(Sender, NewState);
87 this.NotifyCommandsCanExecuteChanged();
94 base.SetIsBusy(IsBusy);
95 this.NotifyCommandsCanExecuteChanged();
98 private void NotifyCommandsCanExecuteChanged()
100 this.RevokeCommand.NotifyCanExecuteChanged();
101 this.CompromiseCommand.NotifyCanExecuteChanged();
102 this.TransferCommand.NotifyCanExecuteChanged();
103 this.ChangePasswordCommand.NotifyCanExecuteChanged();
112 private bool canProhibitScreenCapture;
118 private string screenCaptureMode;
124 private string displayMode;
130 private bool restartNeeded;
136 private bool canUseFingerprint;
142 private bool canUseAlternativeAuthenticationMethods;
148 private string authenticationMethod;
154 private string approvedAuthenticationMethod;
160 private string versionNumber;
166 private string buildNumber;
172 private string deviceManufactorer;
178 private string deviceModel;
184 private string devicePlatform;
190 private string deviceVersion;
196 private string buildTime;
205 AppTheme? Result = Application.Current?.UserAppTheme;
207 if (!Result.HasValue || Result.Value == AppTheme.Unspecified)
208 Result = Application.Current?.PlatformAppTheme;
210 return Result ?? AppTheme.Unspecified;
226 switch (e.PropertyName)
228 case nameof(this.DisplayMode):
229 if (!this.initializing && Enum.TryParse(
this.DisplayMode, out AppTheme Theme) && Theme !=
CurrentDisplayMode)
235 case nameof(this.ScreenCaptureMode):
236 if (!this.initializing)
238 switch (this.ScreenCaptureMode)
241 await PermitScreenCapture();
245 await ProhibitScreenCapture();
252 if (!this.initializing &&
263 this.AuthenticationMethod = this.ApprovedAuthenticationMethod;
265 if (this.Page is not
null)
275 this.Page.Fingerprint.IsChecked =
false;
276 this.Page.UsePassword.IsChecked =
true;
280 this.Page.UsePassword.IsChecked =
false;
281 this.Page.Fingerprint.IsChecked =
true;
300 private static string GetBuildTime()
302 Assembly assembly = Assembly.GetExecutingAssembly();
304 const string BuildVersionMetadataPrefix =
"+build";
306 AssemblyInformationalVersionAttribute? attribute = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
307 if (attribute?.InformationalVersion !=
null)
309 string value = attribute.InformationalVersion;
311 int datePosition = value.IndexOf(BuildVersionMetadataPrefix, System.StringComparison.OrdinalIgnoreCase);
312 if (datePosition > 0)
314 value = value.Substring(datePosition + BuildVersionMetadataPrefix.Length);
328 internal async Task ChangePassword()
372 private static async Task PermitScreenCapture()
374 if (!
ServiceRef.PlatformSpecific.CanProhibitScreenCapture)
380 ServiceRef.PlatformSpecific.ProhibitScreenCapture =
false;
383 private static async Task ProhibitScreenCapture()
385 if (!
ServiceRef.PlatformSpecific.CanProhibitScreenCapture)
391 ServiceRef.PlatformSpecific.ProhibitScreenCapture =
true;
397 if (this.RestartNeeded)
404 private async Task Revoke()
431 if (RevokedIdentity is not
null)
447 private async Task Compromise()
463 if (succeeded && CompromisedIdentity is not
null)
477 private async Task Transfer()
485 if (Password is
null)
501 StringBuilder Xml =
new();
504 using (XmlWriter Output = XmlWriter.Create(Xml, Settings))
510 Output.WriteStartElement(
"Pin");
511 Output.WriteAttributeString(
"pin", Password);
512 Output.WriteEndElement();
524 Output.WriteEndElement();
525 Output.WriteEndElement();
528 using RandomNumberGenerator Rnd = RandomNumberGenerator.Create();
529 byte[] Data = Encoding.UTF8.GetBytes(Xml.ToString());
530 byte[] Key =
new byte[16];
531 byte[] IV =
new byte[16];
536 using Aes Aes = Aes.Create();
539 Aes.Mode = CipherMode.CBC;
540 Aes.Padding = PaddingMode.PKCS7;
542 using ICryptoTransform Transform = Aes.CreateEncryptor(Key, IV);
543 byte[] Encrypted = Transform.TransformFinalBlock(Data, 0, Data.Length);
547 using (XmlWriter Output = XmlWriter.Create(Xml, Settings))
550 Output.WriteAttributeString(
"base64", Convert.ToBase64String(Encrypted));
551 Output.WriteAttributeString(
"once",
"true");
552 Output.WriteAttributeString(
"expires",
XML.
Encode(DateTime.UtcNow.AddMinutes(1)));
553 Output.WriteEndElement();
558 foreach (XmlNode N
in Response.ChildNodes)
563 string Url =
"obinfo:" + Constants.Domains.IdDomain +
":" + Code +
":" +
564 Convert.ToBase64String(Key) +
":" + Convert.ToBase64String(IV);
589 private static async Task ChangeLanguage()
595 private void ToggleDarkMode()
597 this.DisplayMode =
"Dark";
The Application class, representing an instance of the Neuro-Access app.
static Task SetRegistrationPageAsync()
Switches the application to the on-boarding experience.
static Task< bool > AuthenticateUser(AuthenticationPurpose Purpose, bool Force=false)
Authenticates the user using the configured authentication method.
static async Task CheckUserBlocking()
Verify if the user is blocked and show an alert
static async Task< string?> InputPassword(AuthenticationPurpose Purpose)
Asks the user to input its password. Password is verified before being returned.
const string OnboardingDomain
Neuro-Access onboarding domain.
A set of never changing property constants and helpful values.
Base class that references services in the app.
static ILogService LogService
Log service.
static INetworkService NetworkService
Network service.
static IUiService UiService
Service serializing and managing UI-related tasks.
static ITagProfile TagProfile
TAG Profile service.
static ICryptoService CryptoService
Crypto service.
static IStringLocalizer Localizer
Localization service
static IXmppService XmppService
The XMPP service for XMPP communication.
static async Task< bool > AreYouSure(string Message)
Asks the user to confirm an action.
static void GoToRegistrationStep(RegistrationStep NewStep)
Set a new registration step
A page to display when the user wants to transfer an identity.
Main page for App settings.
The view model to bind to for when displaying the settings page.
override void SetIsBusy(bool IsBusy)
Sets the IsBusy property.
override async Task OnInitialize()
Method called when view is initialized for the first time. Use this method to implement registration ...
override async Task GoBack()
Method called when user wants to navigate to the previous screen.
SettingsViewModel()
Creates an instance of the SettingsViewModel class.
static AppTheme CurrentDisplayMode
Current display mode
override async void OnPropertyChanged(PropertyChangedEventArgs e)
override Task XmppService_ConnectionStateChanged(object? Sender, XmppState NewState)
Listens to connection state changes from the XMPP server.
bool CanExecuteCommands
Used to find out if a command can execute
A view model that holds the XMPP state.
Helps with common XML-related tasks.
static string Attribute(XmlElement E, string Name)
Gets the value of an XML attribute.
static string Encode(string s)
Encodes a string for use in XML.
static XmlWriterSettings WriterSettings(bool Indent, bool OmitXmlDeclaration)
Gets an XML writer settings object.
Adds support for legal identities, smart contracts and signatures to an XMPP client.
const string NamespaceOnboarding
http://waher.se/schema/Onboarding/v1.xsd
string Id
ID of the legal identity
The requesting entity does not possess the necessary permissions to perform an action that only certa...
AuthenticationMethod AuthenticationMethod
How the user authenticates itself with the App.
string? Account
The account name for this profile
void SetTheme(AppTheme Theme)
Sets the preferred theme.
Task CompromiseLegalIdentity(LegalIdentity compromisedIdentity)
Sets the current LegalIdentity to the compromised identity, and reverses the Step property.
string? XmppPasswordHash
A hash of the current XMPP password.
Task ClearLegalIdentity()
Revert the Set LegalIdentity
string? XmppPasswordHashMethod
The hash method used for hashing the XMPP password.
Task RevokeLegalIdentity(LegalIdentity revokedIdentity)
Sets the current LegalIdentity to the revoked identity, and reverses the Step property.
LegalIdentity? LegalIdentity
The legal identity of the current user/profile.
void SetAccount(string AccountName, string ClientPasswordHash, string ClientPasswordHashMethod)
Set the account name and password for a new account.
string? Domain
The domain this profile is connected to.
AuthenticationMethod
How the user authenticates itself with the App.
RegistrationStep
The different steps of a TAG Profile registration journey.
AuthenticationPurpose
Purpose for requesting the user to authenticate itself.
class RegistrationPageMessage(RegistrationStep Step)
RegistrationPage view change message
XmppState
State of XMPP connection.