4using CommunityToolkit.Mvvm.Messaging;
41 public async Task<bool>
TryOpenLink(Uri Link,
bool ShowErrorIfUnable)
49 await this.ScanQrCode(Link.ToString());
58 if (ShowErrorIfUnable)
68 private async Task ScanQrCode(
string Url)
70 if (
string.IsNullOrEmpty(Url))
85 string[] Parts = Url.Split(
':');
87 if (Parts.Length != 5)
98 string Domain = Parts[1];
99 string Code = Parts[2];
100 string KeyStr = Parts[3];
101 string IVStr = Parts[4];
107 Uri =
new Uri(
"https://" + Domain +
"/Onboarding/GetInfo");
126 new KeyValuePair<string, string>(
"Accept",
"text/plain"));
132 EncryptedStr = (string)Decoded.
Decoded;
147 byte[] Key = Convert.FromBase64String(KeyStr);
148 byte[] IV = Convert.FromBase64String(IVStr);
149 byte[] Encrypted = Convert.FromBase64String(EncryptedStr);
151 using Aes Aes = Aes.Create();
154 Aes.Mode = CipherMode.CBC;
155 Aes.Padding = PaddingMode.PKCS7;
157 using ICryptoTransform Decryptor = Aes.CreateDecryptor(Key, IV);
158 byte[] Decrypted = Decryptor.TransformFinalBlock(Encrypted, 0, Encrypted.Length);
159 string Xml = Encoding.UTF8.GetString(Decrypted);
161 XmlDocument Doc =
new()
163 PreserveWhitespace =
true
169 throw new Exception(
"Invalid Invitation XML");
171 LinkedList<XmlElement> ToProcess =
new();
172 ToProcess.AddLast(Doc.DocumentElement);
174 bool AccountDone =
false;
175 XmlElement? LegalIdDefinition =
null;
178 while (ToProcess.First is not
null)
180 XmlElement E = ToProcess.First.Value;
181 ToProcess.RemoveFirst();
190 await SelectDomain(Domain, KeyStr, Secret);
209 string PasswordMethod =
XML.
Attribute(E,
"passwordMethod");
217 await SelectDomain(Domain,
string.Empty,
string.Empty);
219 if (!await this.ConnectToAccount(UserName, Password, PasswordMethod,
string.Empty, LegalIdDefinition, Pin ??
string.Empty))
222 throw new Exception(
"Invalid account.");
229 LegalIdDefinition = E;
237 foreach (XmlNode N
in E.ChildNodes)
239 if (N is XmlElement E2)
241 ToProcess.AddLast(E2);
247 throw new Exception(
"Invalid Invitation XML");
251 if (AccountDone && LegalIdDefinition is not
null)
255 else if (AccountDone)
275 private static async Task SelectDomain(
string Domain,
string Key,
string Secret)
277 bool DefaultConnectivity;
281 (
string HostName,
int PortNumber,
bool IsIpAddress) = await
ServiceRef.
NetworkService.LookupXmppHostnameAndPort(Domain);
287 DefaultConnectivity =
false;
293 private async Task<bool> ConnectToAccount(
string AccountName,
string Password,
string PasswordMethod,
string LegalIdentityJid, XmlElement? LegalIdDefinition,
string Pin)
299 DateTime Now = DateTime.Now;
303 bool ServiceDiscoverySucceeded;
311 ServiceDiscoverySucceeded =
true;
316 bool DestroyContractsClient =
false;
322 DestroyContractsClient =
true;
327 if (LegalIdDefinition is not
null)
336 if ((
string.IsNullOrEmpty(LegalIdentityJid) ||
string.Compare(LegalIdentityJid, Identity.
Id, StringComparison.OrdinalIgnoreCase) == 0) &&
339 Identity.
From <= Now &&
340 Identity.
To >= Now &&
347 ApprovedIdentity = Identity;
351 CreatedIdentity ??= Identity;
360 LegalIdentity? SelectedIdentity = ApprovedIdentity ?? CreatedIdentity;
364 if (SelectedIdentity is not
null)
367 SelectedId = SelectedIdentity.
Id;
374 SelectedId =
string.Empty;
377 if (!
string.IsNullOrEmpty(Pin))
379 ServiceRef.TagProfile.LocalPassword = Pin;
384 if (Identity.
Id == SelectedId)
389 switch (Identity.
State)
400 if (DestroyContractsClient)
411 (
bool Succeeded,
string? ErrorMessage,
string[]? Alternatives) = await
ServiceRef.
XmppService.TryConnectAndConnectToAccount(
414 typeof(
App).Assembly, OnConnected);
420 ErrorMessage ??
string.Empty,
Represents an instance of the Neuro-Access app.
static void ValidateCertificateCallback(object? Sender, RemoteCertificateEventArgs Args)
Callback for validating SSL certificates. This method is called when a remote certificate is received...
const string Default
The default language code.
const string Onboarding
Onboarding URI Scheme (obinfo)
static ? string GetScheme(string Url)
Gets the predefined scheme from an IoT Code
A set of never changing property constants and helpful values.
Grade Supports(Uri Link)
How well the link opener supports a given link
OnboardingLink()
Opens onboarding links.
async Task< bool > TryOpenLink(Uri Link, bool ShowErrorIfUnable)
Tries to open a link If the link was opened.
A strongly-typed resource class, for looking up localized strings, etc.
static string UnableToAccessInvitation
Looks up a localized string similar to Unable to access invitation information..
static string UnableToConnectTo
Looks up a localized string similar to Unable to connect to {0}.
static string InvalidInvitationCode
Looks up a localized string similar to Invalid invitation code..
static string ThisCodeCannotBeClaimedAtThisTime
Looks up a localized string similar to This code represents a Neuro-Access invitation,...
static string Ok
Looks up a localized string similar to OK.
static string InvitedToCreateAccountOnDomain
Looks up a localized string similar to You have been invited to create an account on {0}....
static string ErrorTitle
Looks up a localized string similar to An error has occurred.
static string InvitationAccepted
Looks up a localized string similar to Invitation accepted.
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 INavigationService NavigationService
The navigation service for navigating between pages.
static ITagProfile TagProfile
TAG Profile service.
static IReportingStringLocalizer Localizer
Localization service
static IXmppService XmppService
The XMPP service for XMPP communication.
A base class for all view models, inheriting from the BindableObject. NOTE: using this class requir...
static void GoToRegistrationStep(RegistrationStep NewStep)
Set a new registration step
Navigation arguments for onboarding flow. Scenario determines dynamic starting step.
Contains information about a binary response to a content request.
string ContentType
Internet Content-Type of encoded object.
void AssertOk()
Asserts response is OK.
byte[] Encoded
Encoded object.
Contains information about a response to a content request.
object Decoded
Decoded object.
void AssertOk()
Asserts response is OK.
Static class managing encoding and decoding of internet content.
static Task< ContentResponse > PostAsync(Uri Uri, object Data, params KeyValuePair< string, string >[] Headers)
Posts to a resource, using a Uniform Resource Identifier (or Locator).
static Task< ContentResponse > DecodeAsync(string ContentType, byte[] Data, Encoding Encoding, KeyValuePair< string, string >[] Fields, Uri BaseUri)
Decodes an object.
Helps with common XML-related tasks.
static string Attribute(XmlElement E, string Name)
Gets the value of an XML attribute.
Adds support for legal identities, smart contracts and signatures to an XMPP client.
Task< bool > ImportKeys(string Xml)
Imports keys
Task< LegalIdentity > ObsoleteLegalIdentityAsync(string LegalIdentityId)
Obsoletes one of the legal identities of the account, given its ID.
Task< bool > HasPrivateKey(LegalIdentity Identity)
Checks if the private key of a legal identity is available. Private keys are required to be able to s...
const string NamespaceOnboarding
http://waher.se/schema/Onboarding/v1.xsd
Task< LegalIdentity[]> GetLegalIdentitiesAsync()
Gets legal identities registered with the account.
override void Dispose()
Disposes of the extension.
bool HasClientPublicKey
If the identity has a client public key
DateTime From
From what point in time the legal identity is valid.
DateTime To
To what point in time the legal identity is valid.
IdentityState State
Current state of identity
string Id
ID of the legal identity
bool ValidateClientSignature()
Validates the client signature of the legal identity
bool HasClientSignature
If the identity has a client signature
Manages an XMPP client connection. Implements XMPP, as defined in https://tools.ietf....
string PasswordHashMethod
Password hash method.
bool TryGetExtension(Type Type, out IXmppExtension Extension)
Tries to get a registered extension of a specific type from the client.
string PasswordHash
Hash value of password. Depends on method used to authenticate user.
Class containing credentials for an XMPP client connection.
const int DefaultPort
Default XMPP Server port.
Interface for classes that can open links.
RegistrationStep Step
This profile's current registration step.
void SetDomain(string DomainName, bool DefaultXmppConnectivity, string Key, string Secret)
Set the domain name to connect to.
void SetXmppPasswordNeedsUpdating(bool Value)
Sets the local flag for if xmpp password needs updating.
string? ApiKey
API Key, for creating new account.
string? LegalJid
The Jabber Legal JID for this user/profile.
string? ApiSecret
API Secret, for creating new account.
bool DefaultXmppConnectivity
If connecting to the domain can be done using default parameters (host=domain, default c2s port).
bool NeedsUpdating()
Returns true if the current ITagProfile needs to have its values updated, false otherwise.
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.
Task SetAccountAndLegalIdentity(string AccountName, string ClientPasswordHash, string ClientPasswordHashMethod, LegalIdentity Identity)
Set the account name and password for an existing account.
RegistrationStep
The different steps of a TAG Profile registration journey.
OnboardingScenario
Distinct onboarding scenarios.
class OnboardingLinkProcessingMessage(bool isProcessing)
Signals that an onboarding link is being processed (start/stop). Used by GetStarted view to toggle a ...
IdentityState
Lists recognized legal identity states.