1using System.ComponentModel;
2using System.Globalization;
3using System.Reflection;
7using CommunityToolkit.Mvvm.ComponentModel;
8using CommunityToolkit.Mvvm.Input;
9using CommunityToolkit.Mvvm.Messaging;
36 private const string allowed =
"Allowed";
37 private const string prohibited =
"Prohibited";
39 private readonly
bool initializing =
false;
47 this.initializing =
true;
51 this.ScreenCaptureMode = ServiceRef.PlatformSpecific.ProhibitScreenCapture ? prohibited : allowed;
54 this.CanUseAlternativeAuthenticationMethods = this.CanUseFingerprint;
61 this.VersionNumber = AppInfo.VersionString;
62 this.BuildNumber = AppInfo.BuildString;
63 this.BuildTime = GetBuildTime();
64 this.DeviceManufactorer = DeviceInfo.Manufacturer.ToString();
65 this.DeviceModel = DeviceInfo.Model.ToString();
66 this.DevicePlatform = DeviceInfo.Platform.ToString();
67 this.DeviceVersion = DeviceInfo.Version.ToString();
71 this.initializing =
false;
85 await base.OnInitializeAsync();
86 this.NotifyCommandsCanExecuteChanged();
92 return MainThread.InvokeOnMainThreadAsync(async () =>
94 await base.XmppService_ConnectionStateChanged(Sender, NewState);
96 this.NotifyCommandsCanExecuteChanged();
103 base.SetIsBusy(IsBusy);
104 this.NotifyCommandsCanExecuteChanged();
107 private void NotifyCommandsCanExecuteChanged()
109 this.RevokeCommand.NotifyCanExecuteChanged();
110 this.CompromiseCommand.NotifyCanExecuteChanged();
111 this.TransferCommand.NotifyCanExecuteChanged();
112 this.ChangePasswordCommand.NotifyCanExecuteChanged();
115 public bool IsBetaEnabled
122 ServiceRef.TagProfile.HasBetaFeatures = value;
133 private bool canProhibitScreenCapture;
139 private string screenCaptureMode;
145 private string displayMode;
151 private bool restartNeeded;
157 private bool canUseFingerprint;
163 private bool canUseAlternativeAuthenticationMethods;
169 private string authenticationMethod;
175 private string approvedAuthenticationMethod;
181 private string versionNumber;
187 private string buildNumber;
193 private string deviceManufactorer;
199 private string deviceModel;
205 private string devicePlatform;
211 private string deviceVersion;
217 private string buildTime;
226 AppTheme? Result = Application.Current?.UserAppTheme;
228 if (!Result.HasValue)
229 Result = Application.Current?.PlatformAppTheme;
231 return Result ?? AppTheme.Unspecified;
247 switch (e.PropertyName)
249 case nameof(this.DisplayMode):
250 if (!this.initializing && Enum.TryParse(
this.DisplayMode, out AppTheme Theme) && Theme !=
CurrentDisplayMode)
256 case nameof(this.ScreenCaptureMode):
257 if (!this.initializing)
259 switch (this.ScreenCaptureMode)
262 await PermitScreenCapture();
266 await ProhibitScreenCapture();
273 if (!this.initializing &&
277 if (await this.authenticationService.AuthenticateUserAsync(
AuthenticationPurpose.ChangeAuthenticationMethod,
true))
284 this.AuthenticationMethod = this.ApprovedAuthenticationMethod;
286 if (this.Page is not
null)
296 this.Page.Fingerprint.IsChecked =
false;
297 this.Page.UsePassword.IsChecked =
true;
301 this.Page.UsePassword.IsChecked =
false;
302 this.Page.Fingerprint.IsChecked =
true;
321 private static string GetBuildTime()
323 Assembly Assembly = Assembly.GetExecutingAssembly();
325 const string BuildVersionMetadataPrefix =
"+build";
327 AssemblyInformationalVersionAttribute? Attribute = Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
328 if (Attribute?.InformationalVersion is not
null)
330 string Value = Attribute.InformationalVersion;
332 int DatePosition = Value.IndexOf(BuildVersionMetadataPrefix,
System.StringComparison.OrdinalIgnoreCase);
333 if (DatePosition > 0)
335 Value = Value[(DatePosition + BuildVersionMetadataPrefix.Length)..];
349 internal async Task ChangePassword()
354 await this.authenticationService.CheckUserBlockingAsync();
355 if (await this.authenticationService.AuthenticateUserAsync(
AuthenticationPurpose.ChangePassword,
true) ==
false)
384 private static async Task PermitScreenCapture()
392 ServiceRef.PlatformSpecific.ProhibitScreenCapture =
false;
395 private static async Task ProhibitScreenCapture()
403 ServiceRef.PlatformSpecific.ProhibitScreenCapture =
true;
409 if (this.RestartNeeded)
410 await
App.StopAsync();
416 private async Task Revoke()
426 if (!await this.authenticationService.AuthenticateUserAsync(
AuthenticationPurpose.RevokeIdentity,
true))
443 if (RevokedIdentity is not
null)
458 private async Task Compromise()
468 if (!await this.authenticationService.AuthenticateUserAsync(
AuthenticationPurpose.ReportAsCompromized,
true))
474 if (succeeded && CompromisedIdentity is not
null)
488 private async Task Transfer()
506 string? Password = await this.authenticationService.InputPasswordAsync(
AuthenticationPurpose.TransferIdentity);
507 if (Password is
null)
514 StringBuilder Xml =
new();
517 using (XmlWriter Output = XmlWriter.Create(Xml, Settings))
523 Output.WriteStartElement(
"Pin");
524 Output.WriteAttributeString(
"pin", Password);
525 Output.WriteEndElement();
537 Output.WriteEndElement();
538 Output.WriteEndElement();
541 using RandomNumberGenerator Rnd = RandomNumberGenerator.Create();
542 byte[] Data = Encoding.UTF8.GetBytes(Xml.ToString());
543 byte[] Key =
new byte[16];
544 byte[] IV =
new byte[16];
549 using Aes Aes = Aes.Create();
552 Aes.Mode = CipherMode.CBC;
553 Aes.Padding = PaddingMode.PKCS7;
555 using ICryptoTransform Transform = Aes.CreateEncryptor(Key, IV);
556 byte[] Encrypted = Transform.TransformFinalBlock(Data, 0, Data.Length);
560 using (XmlWriter Output = XmlWriter.Create(Xml, Settings))
563 Output.WriteAttributeString(
"base64", Convert.ToBase64String(Encrypted));
564 Output.WriteAttributeString(
"once",
"true");
565 Output.WriteAttributeString(
"expires",
XML.
Encode(DateTime.UtcNow.AddMinutes(1)));
566 Output.WriteEndElement();
571 foreach (XmlNode N
in Response.ChildNodes)
576 string Url =
"obinfo:" + Constants.Domains.IdDomain +
":" + Code +
":" +
577 Convert.ToBase64String(Key) +
":" + Convert.ToBase64String(IV);
602 private static async Task ChangeLanguage()
608 private void ToggleDarkMode()
610 this.DisplayMode =
"Dark";
614 private async Task ClearCacheAsync()
627 if (!
string.IsNullOrWhiteSpace(domain))
628 await invalidation.InvalidateByParentId($
"KycProcess:{domain}", scope:
"Kyc");
629 if (!
string.IsNullOrWhiteSpace(pubSub))
630 await invalidation.InvalidateByParentId(pubSub, scope:
"Branding");
633 await
ServiceRef.ThemeService.ClearBrandingCacheForCurrentDomain();
637 IEnumerable<KycReference> drafts = Array.Empty<
KycReference>();
660 public void SetBetaFeaturesEnabled(
bool Enabled)
662 this.IsBetaEnabled = Enabled;
Represents an instance of the Neuro-Access app.
const string OnboardingDomain
Neuro-Access onboarding domain.
A set of never changing property constants and helpful values.
A strongly-typed resource class, for looking up localized strings, etc.
static string Yes
Looks up a localized string similar to Yes.
static string UnexpectedResponse
Looks up a localized string similar to An unexpected response was received..
static string AreYouSureYouWantToRevokeYourLegalIdentity
Looks up a localized string similar to Are you sure you want to revoke your identity from the applica...
static string CacheCleared
Looks up a localized string similar to Cache cleared.
static string AreYouSureYouWantToTransferYourLegalIdentity
Looks up a localized string similar to Are you sure you want to transfer your identity from this devi...
static string PasswordChanged
Looks up a localized string similar to PIN has been successfully changed..
static string Confirm
Looks up a localized string similar to Confirm.
static string Ok
Looks up a localized string similar to OK.
static string AreYouSureYouWantToReportYourLegalIdentityAsCompromized
Looks up a localized string similar to Are you sure you want to report your identity as compromised,...
static string No
Looks up a localized string similar to No.
static string SuccessTitle
Looks up a localized string similar to Success.
static string ErrorTitle
Looks up a localized string similar to An error has occurred.
Contains information about a file in the local cache.
Contains a local reference to a KYC process.
Base class that references services in the app.
static IServiceProvider Provider
The service provider for the app. This is set before the app is started, and will be used to resolve ...
static ILogService LogService
Log service.
static INetworkService NetworkService
Network service.
static IUiService UiService
Service serializing and managing UI-related tasks.
static INavigationService NavigationService
The navigation service for navigating between pages.
static IPopupService PopupService
Popup service for presenting application popups.
static ITagProfile TagProfile
TAG Profile service.
static IReportingStringLocalizer Localizer
Localization service
static IXmppService XmppService
The XMPP service for XMPP communication.
static IPlatformSpecific PlatformSpecific
Localization service
static async Task< bool > AreYouSure(string Message)
Asks the user to confirm an action.
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 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
override async Task OnInitializeAsync()
Method called when view is initialized for the first time. Use this method to implement registration ...
Navigation arguments for onboarding flow. Scenario determines dynamic starting step.
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...
Static interface for database persistence. In order to work, a database provider has to be assigned t...
static Task< IEnumerable< object > > FindDelete(string Collection, params string[] SortOrder)
Finds objects in a given collection and deletes them in the same atomic operation.
static IDatabaseProvider Provider
Registered database provider.
static async Task Delete(object Object)
Deletes an object in the database.
static Task< IEnumerable< object > > Find(string Collection, params string[] SortOrder)
Finds objects in a given collection.
This filter selects objects that have a named field greater or equal to a given value.
Static class that dynamically manages types and interfaces available in the runtime environment.
static object InstantiateDefault(Type Type, params object[] Arguments)
Returns an instance of the type Type . If one needs to be created, it is. If the constructor requires...
bool HasBetaFeatures
If the user has Beta features enabled
AuthenticationMethod AuthenticationMethod
How the user authenticates itself with the App.
string? Account
The account name for this profile
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.
string? Domain
The domain this profile is connected to.
string? PubSubJid
The XMPP server's PubSub JID.
Task Flush()
Persists any pending changes.
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.