6using System.Threading.Tasks;
37 : base(
"Account/Recover",
38 new KeyValuePair<Type,
Expression>(typeof(Dictionary<string, object>), new
Expression(jsonPattern)),
70 string UserName = (string)Parameters[
"PUserName"]?.AssociatedObjectValue ??
string.Empty;
71 string PersonalNr = (string)Parameters[
"PPersonalNr"]?.AssociatedObjectValue ??
string.Empty;
72 string Country = (string)Parameters[
"PCountry"]?.AssociatedObjectValue ??
string.Empty;
73 string EMail = (string)Parameters[
"PEMail"]?.AssociatedObjectValue ??
string.Empty;
74 string PhoneNr = (string)Parameters[
"PPhoneNr"]?.AssociatedObjectValue ??
string.Empty;
76 if (
string.IsNullOrEmpty(UserName) &&
string.IsNullOrEmpty(PersonalNr))
77 throw new BadRequestException(
"Either User Name or Personal Number with a corresponding country must be provided.");
79 if (
string.IsNullOrEmpty(EMail) &&
string.IsNullOrEmpty(PhoneNr))
82 if (!await
Create.AssertUserNameValid(UserName, Response))
85 LinkedList<LegalIdentity> Matches =
new LinkedList<LegalIdentity>();
87 "RecoverResponse",
"https://waher.se/Schema/BrokerAgent.xsd");
90 if (!
string.IsNullOrEmpty(UserName))
99 await Response.
Return(Result);
104 if (
string.IsNullOrEmpty(PersonalNr))
109 Matches.AddLast(Identity);
128 if (Identity is
null)
131 Matches.AddLast(Identity);
135 if (
string.IsNullOrEmpty(UserName))
137 UserName = Identity.Account;
140 else if (UserName != Identity.Account)
142 LoginAuditor.
Fail(
"Account recovery failed. Provided personal number that matches multiple accounts.", UserName, Request.
RemoteEndPoint,
"HTTPS");
144 throw new UnprocessableEntityException(
"Multiple accounts registered for that person on the server. You need to specify which account you want to recover.");
158 LoginAuditor.
Fail(
"Account recovery failed. Provided personal number does not match provided account.", UserName, Request.
RemoteEndPoint,
"HTTPS");
160 await Response.
Return(Result);
173 await Response.
Return(Result);
179 if (!
string.IsNullOrEmpty(EMail) && Account.EMail != EMail)
183 await Response.
Return(Result);
187 if (!
string.IsNullOrEmpty(PhoneNr))
189 bool PhoneNrMatches =
false;
194 if (
string.IsNullOrEmpty(s))
197 if (ComparePhoneNumbers(s, PhoneNr))
199 PhoneNrMatches =
true;
208 await Response.
Return(Result);
218 if (Matches.First is
null)
220 StringBuilder Xml =
new StringBuilder();
222 Account.AppendAccountXml(Xml,
true);
224 byte[] Data = Encoding.UTF8.GetBytes(Xml.ToString());
229 using (Aes Aes = Aes.Create())
233 Aes.Mode = CipherMode.CBC;
234 Aes.Padding = PaddingMode.PKCS7;
236 using ICryptoTransform Transform = Aes.CreateEncryptor(Key, IV);
238 Encrypted = Transform.TransformFinalBlock(Data, 0, Data.Length);
243 Xml.Append(
"<Info xmlns=\"http://waher.se/schema/Onboarding/v1.xsd\" base64=\"");
244 Xml.Append(Convert.ToBase64String(Encrypted));
245 Xml.Append(
"\" once=\"true\" expires=\"");
246 Xml.Append(
XML.
Encode(DateTime.Now.AddHours(1).ToUniversalTime()));
250 XmlElement E = await
Gateway.
XmppClient.IqSetAsync(
"onboarding." + OnboardingDomainName, Xml.ToString());
251 string Code = E.GetAttribute(
"code");
255 Xml.Append(
"obinfo:");
256 Xml.Append(OnboardingDomainName);
260 Xml.Append(Convert.ToBase64String(Key));
262 Xml.Append(Convert.ToBase64String(IV));
264 string Url = Xml.ToString();
265 StringBuilder Markdown =
new StringBuilder();
267 Markdown.AppendLine(
"Account recovery");
268 Markdown.AppendLine(
"===================");
269 Markdown.AppendLine();
270 Markdown.AppendLine(
"Someone has requested to recover access to your TAG ID account.");
271 Markdown.AppendLine(
"If this is not you, you can ignore this message, and the account will not be affected.");
272 Markdown.AppendLine(
"If it is you that has requested to recover your account, scan the following QR code to get access to the account.");
273 Markdown.AppendLine(
"If you view this e-mail in the phone containing the TAG ID app (or derivative), you can also click on the QR code itself.");
274 Markdown.AppendLine(
"This recovery code is only valid for one hour.");
275 Markdown.AppendLine();
276 Markdown.Append(
";
277 Markdown.Append(
Gateway.
GetUrl(
"/QR/" + HttpUtility.UrlEncode(Url) +
"?w=400&h=400&q=2"));
278 Markdown.AppendLine(
")");
279 Markdown.AppendLine();
280 Markdown.Append(
"If you have any questions, please let us know through our [feedback page](");
282 Markdown.AppendLine(
").");
294 if (Latest is
null || Identity.
Created > Latest.Created)
300 if (LatestApproved is
null || Identity.
Created > LatestApproved.Created)
301 LatestApproved = Identity;
304 if (!(LatestApproved is
null) && !(LatestApproved.Attachments is
null))
305 Reviewers = await
LegalComponent.GetPeerReviewers(LatestApproved);
317 StringBuilder Markdown =
new StringBuilder();
319 Markdown.AppendLine(
"User requests account recovery");
320 Markdown.AppendLine(
"==================================");
321 Markdown.AppendLine();
322 Markdown.AppendLine(
"Someone has requested to recover access to an account.");
323 Markdown.AppendLine(
"Following is some information provided in the request.");
324 Markdown.AppendLine();
325 Markdown.AppendLine(
"| Provided by user ||");
326 Markdown.AppendLine(
"|:--------|:--------|");
327 Markdown.Append(
"| User Name | `");
328 Markdown.Append(UserName);
329 Markdown.AppendLine(
"` |");
330 Markdown.Append(
"| Personal Number | `");
331 Markdown.Append(PersonalNr);
332 Markdown.AppendLine(
"` |");
333 Markdown.Append(
"| Country | `");
334 Markdown.Append(Country);
335 Markdown.AppendLine(
"` |");
336 Markdown.Append(
"| e-mail | <mailto:");
337 Markdown.Append(EMail);
338 Markdown.AppendLine(
"> |");
339 Markdown.Append(
"| Phone Number | <tel:");
340 Markdown.Append(PhoneNr);
341 Markdown.AppendLine(
"> |");
342 Markdown.AppendLine();
345 if (!(Locale is
null))
347 Markdown.AppendLine(
"| Remote Endpoint ||");
348 Markdown.AppendLine(
"|:--------|:--------|");
349 Markdown.Append(
"| Country Code | ");
351 Markdown.AppendLine(
" |");
352 Markdown.Append(
"| Country | ");
354 Markdown.AppendLine(
" |");
355 Markdown.Append(
"| Region | ");
357 Markdown.AppendLine(
" |");
358 Markdown.Append(
"| City | ");
360 Markdown.AppendLine(
" |");
361 Markdown.Append(
"| Latitude | ");
363 Markdown.AppendLine(
" |");
364 Markdown.Append(
"| Longitude | ");
366 Markdown.AppendLine(
" |");
369 Markdown.AppendLine(
"No information found about IP address.");
371 Markdown.AppendLine();
373 if (!(LatestApproved is
null))
375 Markdown.AppendLine(
"| Latest Approved ID ||");
376 Markdown.AppendLine(
"|:---------|:---------|");
377 Markdown.Append(
"| ID | [");
379 Markdown.Append(
"](");
381 Markdown.Append(
"?ID=");
382 Markdown.Append(HttpUtility.UrlEncode(LatestApproved.Id));
383 Markdown.AppendLine(
"&Purpose=Review%20recovery%20application) |");
385 LegalComponent.Output(Markdown, LatestApproved.GetTags(
false),
false);
387 else if (!(Latest is
null))
389 Markdown.AppendLine(
"| Latest ID (not approved) ||");
390 Markdown.AppendLine(
"|:------------|:------------|");
391 Markdown.Append(
"| ID | [");
393 Markdown.Append(
"](");
395 Markdown.Append(
"?ID=");
396 Markdown.Append(HttpUtility.UrlEncode(Latest.Id));
397 Markdown.AppendLine(
"&Purpose=Review%20recovery%20application) |");
402 Markdown.AppendLine(
"No Legal ID found.");
414 await Response.
Return(Result);
417 private static bool ComparePhoneNumbers(
string Nr1,
string Nr2)
419 return OnlyDigits(Nr1) == OnlyDigits(Nr2);
422 private static string OnlyDigits(
string s)
424 StringBuilder sb =
new StringBuilder();
426 foreach (
char ch
in s)
428 if (
char.IsDigit(ch))
432 return sb.ToString();
Helps with parsing of commong data types.
static string Encode(bool x)
Encodes a Boolean for use in XML and other formats.
Contains a markdown document. This markdown document class supports original markdown,...
static string Encode(string s)
Encodes all special characters in a string so that it can be included in a markdown document without ...
A Named dictionary is a dictionary, with a local name and a namespace. Use it to return content that ...
Helps with common XML-related tasks.
static string Encode(string s)
Encodes a string for use in XML.
Static class managing the runtime environment of the IoT Gateway.
static byte[] NextBytes(int NrBytes)
Generates an array of random bytes.
static Task SendNotification(Graph Graph)
Sends a graph as a notification message to configured notification recipients.
static string GetUrl(string LocalResource)
Gets a URL for a resource.
static XmppClient XmppClient
XMPP Client connection of gateway.
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repe...
Base class for all HTTP authentication schemes, as defined in RFC-7235: https://datatracker....
Represents an HTTP request.
string RemoteEndPoint
Remote end-point.
Represets a response of an HTTP client request.
Task Return(Exception ex)
Returns an error to the client.
The server is currently unable to handle the request due to a temporary overloading or maintenance of...
The request was well-formed but was unable to be followed due to semantic errors.
bool IsComponentDomain(CaseInsensitiveString Domain, bool IncludeAlternativeDomains)
Checks if a domain is the component domain, or optionally, an alternative component domain.
override string ToString()
Static interface for database persistence. In order to work, a database provider has to be assigned t...
static Task< IEnumerable< object > > Find(string Collection, params string[] SortOrder)
Finds objects in a given collection.
This filter selects objects that conform to all child-filters provided.
This filter selects objects that have a named field equal to a given value.
Static class managing loading of resources stored as embedded resources or in content files.
static string LoadResourceAsText(string ResourceName)
Loads a text resource from an embedded resource.
Class managing a script expression.
Class that monitors login events, and help applications determine malicious intent....
static async void Success(string Message, string UserName, string RemoteEndPoint, string Protocol, params KeyValuePair< string, object >[] Tags)
Handles a successful login attempt.
static void Fail(string Message, string UserName, string RemoteEndPoint, string Protocol)
Handles a failed login attempt.
Contains information about a broker account.
CaseInsensitiveString EMail
E-mail address associated with account.
CaseInsensitiveString UserName
User Name of account
string CountryCode
ISO Country Code
string Country
Name of country
double Longitude
Longitude
IdentityState State
Current state of identity
DateTime Created
When the identity object was created
Legal (digital identities, smart contracts) service component.
static Task< string > GetOnboardingNeuronDomainName()
Gets the domain name of the Nnboarding Neuron.
Contains a reference to a legal identity, and its related PNR and COUNTRY fields. Allows for distribu...
CaseInsensitiveString Provider
Provider of identity
CaseInsensitiveString LegalId
Legal ID reference
Provides the user with options to control notifications from the Broker.
static BrokerNotificationConfiguration Instance
Current instance of configuration.
bool AccountRecoveryRequest
If a notification should be sent when an account recovery request has been received.
Creates an account on the server.
Called when a user wants to recover its account.
Recover()
Called when a user wants to recover its account.
override HttpAuthenticationScheme[] GetAuthenticationSchemes(HttpRequest Request)
Any authentication schemes used to authenticate users before access is granted to the corresponding r...
override async Task POST(HttpRequest Request, HttpResponse Response, Dictionary< string, IElement > Parameters)
Executes the POST method on the resource.
Abstract base class for agent resources supporting the POST method.
async Task CheckBlocks(HttpRequest Request)
Checks if the client is blocked.
Service Module hosting the XMPP broker and its components.
static Task< bool > SendMailMessage(string To, string Subject, string Markdown)
Sends a mail message
static Task< IP4Localization > FindIpAddress(string RemoteEndPoint)
Finds locale information about an IP Address.
IdentityState
Lists recognized legal identity states.