Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
PetitionSignatureViewModel.cs
1using CommunityToolkit.Mvvm.ComponentModel;
2using CommunityToolkit.Mvvm.Input;
8using System.Collections.ObjectModel;
11
13{
18 {
19 private readonly PhotosLoader photosLoader;
20 private readonly string? requestorFullJid;
21 private readonly string? signatoryIdentityId;
22 private readonly string? petitionId;
23 private readonly byte[]? contentToSign;
24
30 : base()
31 {
32 this.photosLoader = new PhotosLoader(this.Photos);
33
34 if (Args is null)
35 return;
36
37 this.RequestorIdentity = Args.RequestorIdentity;
38 this.requestorFullJid = Args.RequestorFullJid;
39 this.signatoryIdentityId = Args.SignatoryIdentityId;
40 this.contentToSign = Args.ContentToSign;
41 this.petitionId = Args.PetitionId;
42 this.Purpose = Args.Purpose;
43 }
44
46 protected override async Task OnInitialize()
47 {
48 await base.OnInitialize();
49
50 this.AssignProperties();
51
52 if (this.RequestorIdentity?.Attachments is not null)
53 _ = this.photosLoader.LoadPhotos(this.RequestorIdentity.Attachments, SignWith.LatestApprovedId);
54 }
55
57 protected override async Task OnDispose()
58 {
59 this.photosLoader.CancelLoadPhotos();
60
61 await base.OnDispose();
62 }
63
67 public ObservableCollection<Photo> Photos { get; } = [];
68
72 public LegalIdentity? RequestorIdentity { get; private set; }
73
74 [RelayCommand]
75 private async Task Accept()
76 {
77 if (!await App.AuthenticateUser(AuthenticationPurpose.AcceptPetitionRequest))
78 return;
79
80 bool Succeeded = await ServiceRef.NetworkService.TryRequest(async () =>
81 {
82 byte[] Signature = await ServiceRef.XmppService.Sign(this.contentToSign!, SignWith.LatestApprovedId);
83
84 await ServiceRef.XmppService.SendPetitionSignatureResponse(this.signatoryIdentityId, this.contentToSign!, Signature,
85 this.petitionId!, this.requestorFullJid!, true);
86 });
87
88 if (Succeeded)
89 await this.GoBack();
90 }
91
92 [RelayCommand]
93 private async Task Decline()
94 {
95 bool Succeeded = await ServiceRef.NetworkService.TryRequest(() =>
96 {
97 return ServiceRef.XmppService.SendPetitionSignatureResponse(this.signatoryIdentityId,
98 this.contentToSign!, [], this.petitionId!, this.requestorFullJid!, false);
99 });
100
101 if (Succeeded)
102 await this.GoBack();
103 }
104
105 [RelayCommand]
106 private async Task Ignore()
107 {
108 await this.GoBack();
109 }
110
114 public override Task<string> Title => Task.FromResult(this.FullName);
115
116 // Full name of requesting entity.
117 public string FullName => ContactInfo.GetFullName(this.FirstName, this.MiddleNames, this.LastNames);
118
119 // The display name of the identity. If organization name is available, it is used, otherwise the full name.
120 public string? DisplayName => string.IsNullOrEmpty(this.Domain) ? (this.HasOrg ? this.OrgName : this.FullName) : this.Domain;
121
122 #region Properties
123
127 [ObservableProperty]
128 private DateTime? created;
129
133 [ObservableProperty]
134 private DateTime? updated;
135
139 [ObservableProperty]
140 private DateTime? expires;
141
145 [ObservableProperty]
146 private string? legalId;
147
151 [ObservableProperty]
152 private string? networkId;
153
157 [ObservableProperty]
158 private IdentityState? state;
159
163 [ObservableProperty]
164 private DateTime? from;
165
169 [ObservableProperty]
170 private DateTime? to;
171
175 [ObservableProperty]
176 [NotifyPropertyChangedFor(nameof(FullName))]
177 [NotifyPropertyChangedFor(nameof(DisplayName))]
178
179 private string? firstName;
180
184 [ObservableProperty]
185 [NotifyPropertyChangedFor(nameof(FullName))]
186 [NotifyPropertyChangedFor(nameof(DisplayName))]
187
188 private string? middleNames;
189
193 [ObservableProperty]
194 [NotifyPropertyChangedFor(nameof(FullName))]
195 [NotifyPropertyChangedFor(nameof(DisplayName))]
196 private string? lastNames;
197
198 [ObservableProperty]
199 [NotifyPropertyChangedFor(nameof(DisplayName))]
200 private string? domain;
201
205 [ObservableProperty]
206 private string? personalNumber;
207
211 [ObservableProperty]
212 private string? address;
213
217 [ObservableProperty]
218 private string? address2;
219
223 [ObservableProperty]
224 private string? zipCode;
225
229 [ObservableProperty]
230 private string? area;
231
235 [ObservableProperty]
236 private string? city;
237
241 [ObservableProperty]
242 private string? region;
243
247 [ObservableProperty]
248 private string? countryCode;
249
253 [ObservableProperty]
254 private string? nationalityCode;
255
259 [ObservableProperty]
260 private string? gender;
261
265 [ObservableProperty]
266 private DateTime? birthDate;
267
271 [ObservableProperty]
272 [NotifyPropertyChangedFor(nameof(DisplayName))]
273 private string? orgName;
274
278 [ObservableProperty]
279 private string? orgNumber;
280
284 [ObservableProperty]
285 private string? orgDepartment;
286
290 [ObservableProperty]
291 private string? orgRole;
292
296 [ObservableProperty]
297 private string? orgAddress;
298
302 [ObservableProperty]
303 private string? orgAddress2;
304
308 [ObservableProperty]
309 private string? orgZipCode;
310
314 [ObservableProperty]
315 private string? orgArea;
316
320 [ObservableProperty]
321 private string? orgCity;
322
326 [ObservableProperty]
327 private string? orgRegion;
328
332 [ObservableProperty]
333 private string? orgCountryCode;
334
338 [ObservableProperty]
339 [NotifyPropertyChangedFor(nameof(DisplayName))]
340 private bool hasOrg;
341
345 [ObservableProperty]
346 private bool hasPhotos;
347
351 [ObservableProperty]
352 private string? phoneNr;
353
357 [ObservableProperty]
358 private string? eMail;
359
363 [ObservableProperty]
364 private string? deviceId;
365
369 [ObservableProperty]
370 private bool isApproved;
371
375 [ObservableProperty]
376 private string? purpose;
377
381 [ObservableProperty]
382 private ImageSource? firstPhotoSource;
383
387 [ObservableProperty]
388 private int firstPhotoRotation;
389
390 #endregion
391
392 private void AssignProperties()
393 {
394 if (this.RequestorIdentity is not null)
395 {
396 this.Created = this.RequestorIdentity.Created;
397 this.Updated = this.RequestorIdentity.Updated.GetDateOrNullIfMinValue();
398 this.Expires = this.RequestorIdentity.To.GetDateOrNullIfMinValue();
399 this.LegalId = this.RequestorIdentity.Id;
400 this.NetworkId = this.RequestorIdentity.GetJid();
401 this.State = this.RequestorIdentity.State;
402 this.From = this.RequestorIdentity.From.GetDateOrNullIfMinValue();
403 this.To = this.RequestorIdentity.To.GetDateOrNullIfMinValue();
405 this.MiddleNames = this.RequestorIdentity[Constants.XmppProperties.MiddleNames];
407 this.PersonalNumber = this.RequestorIdentity[Constants.XmppProperties.PersonalNumber];
414 this.CountryCode = this.RequestorIdentity[Constants.XmppProperties.Country];
415 this.NationalityCode = this.RequestorIdentity[Constants.XmppProperties.Nationality];
418
419 string BirthDayStr = this.RequestorIdentity[Constants.XmppProperties.BirthDay];
420 string BirthMonthStr = this.RequestorIdentity[Constants.XmppProperties.BirthMonth];
421 string BirthYearStr = this.RequestorIdentity[Constants.XmppProperties.BirthYear];
422
423 if (!string.IsNullOrEmpty(BirthDayStr) && int.TryParse(BirthDayStr, out int BirthDay) &&
424 !string.IsNullOrEmpty(BirthMonthStr) && int.TryParse(BirthMonthStr, out int BirthMonth) &&
425 !string.IsNullOrEmpty(BirthYearStr) && int.TryParse(BirthYearStr, out int BirthYear))
426 {
427 try
428 {
429 this.BirthDate = new DateTime(BirthYear, BirthMonth, BirthDay);
430 }
431 catch (Exception ex)
432 {
433 ServiceRef.LogService.LogException(ex);
434 this.BirthDate = null;
435 }
436 }
437
440 this.OrgDepartment = this.RequestorIdentity[Constants.XmppProperties.OrgDepartment];
443 this.OrgAddress2 = this.RequestorIdentity[Constants.XmppProperties.OrgAddress2];
448 this.OrgCountryCode = this.RequestorIdentity[Constants.XmppProperties.OrgCountry];
449 this.HasOrg =
450 !string.IsNullOrEmpty(this.OrgName) ||
451 !string.IsNullOrEmpty(this.OrgNumber) ||
452 !string.IsNullOrEmpty(this.OrgDepartment) ||
453 !string.IsNullOrEmpty(this.OrgRole) ||
454 !string.IsNullOrEmpty(this.OrgAddress) ||
455 !string.IsNullOrEmpty(this.OrgAddress2) ||
456 !string.IsNullOrEmpty(this.OrgZipCode) ||
457 !string.IsNullOrEmpty(this.OrgArea) ||
458 !string.IsNullOrEmpty(this.OrgCity) ||
459 !string.IsNullOrEmpty(this.OrgRegion) ||
460 !string.IsNullOrEmpty(this.OrgCountryCode);
461 this.HasPhotos = this.Photos.Count > 0;
462 this.PhoneNr = this.RequestorIdentity[Constants.XmppProperties.Phone];
465 this.IsApproved = this.RequestorIdentity.State == IdentityState.Approved;
466 }
467 else
468 {
469 this.Created = DateTime.MinValue;
470 this.Updated = null;
471 this.LegalId = Constants.NotAvailableValue;
472 this.NetworkId = Constants.NotAvailableValue;
473 this.State = IdentityState.Compromised;
474 this.From = null;
475 this.To = null;
476 this.FirstName = Constants.NotAvailableValue;
477 this.MiddleNames = Constants.NotAvailableValue;
478 this.LastNames = Constants.NotAvailableValue;
479 this.PersonalNumber = Constants.NotAvailableValue;
480 this.Address = Constants.NotAvailableValue;
481 this.Address2 = Constants.NotAvailableValue;
482 this.ZipCode = Constants.NotAvailableValue;
483 this.Area = Constants.NotAvailableValue;
484 this.City = Constants.NotAvailableValue;
485 this.Region = Constants.NotAvailableValue;
486 this.CountryCode = Constants.NotAvailableValue;
487 this.NationalityCode = Constants.NotAvailableValue;
488 this.Gender = Constants.NotAvailableValue;
489 this.BirthDate = null;
490 this.OrgName = Constants.NotAvailableValue;
491 this.OrgNumber = Constants.NotAvailableValue;
492 this.OrgDepartment = Constants.NotAvailableValue;
493 this.OrgRole = Constants.NotAvailableValue;
494 this.OrgAddress = Constants.NotAvailableValue;
495 this.OrgAddress2 = Constants.NotAvailableValue;
496 this.OrgZipCode = Constants.NotAvailableValue;
497 this.OrgArea = Constants.NotAvailableValue;
498 this.OrgCity = Constants.NotAvailableValue;
499 this.OrgRegion = Constants.NotAvailableValue;
500 this.OrgCountryCode = Constants.NotAvailableValue;
501 this.HasOrg = false;
502 this.HasPhotos = false;
503 this.PhoneNr = Constants.NotAvailableValue;
504 this.EMail = Constants.NotAvailableValue;
505 this.DeviceId = Constants.NotAvailableValue;
506 this.IsApproved = false;
507 }
508
509 // QR
510 if (this.RequestorIdentity is null)
511 this.RemoveQrCode();
512 else
513 this.GenerateQrCode(Constants.UriSchemes.CreateIdUri(this.RequestorIdentity.Id));
514
515 if (this.IsConnected)
516 this.ReloadPhotos();
517 }
518
520 protected override Task XmppService_ConnectionStateChanged(object? Sender, XmppState NewState)
521 {
522 return MainThread.InvokeOnMainThreadAsync(async () =>
523 {
524 await base.XmppService_ConnectionStateChanged(Sender, NewState);
525
526 if (this.IsConnected)
527 {
528 await Task.Delay(Constants.Timeouts.XmppInit);
529 this.ReloadPhotos();
530 }
531 });
532 }
533
534 private async void ReloadPhotos()
535 {
536 try
537 {
538 this.photosLoader.CancelLoadPhotos();
539
540 Attachment[]? Attachments = this.RequestorIdentity?.Attachments;
541
542 if (Attachments is not null)
543 {
544 Photo? First = await this.photosLoader.LoadPhotos(Attachments, SignWith.LatestApprovedIdOrCurrentKeys);
545
546 this.FirstPhotoSource = First?.Source;
547 this.FirstPhotoRotation = First?.Rotation ?? 0;
548 }
549 }
550 catch (Exception ex)
551 {
552 ServiceRef.LogService.LogException(ex);
553 }
554 }
555
559 [RelayCommand]
560 private async Task Copy(object Item)
561 {
562 try
563 {
564 if (Item is string Label)
565 {
566 if (Label == this.LegalId)
567 {
568 await Clipboard.SetTextAsync(Constants.UriSchemes.IotId + ":" + this.LegalId);
569 await ServiceRef.UiService.DisplayAlert(
570 ServiceRef.Localizer[nameof(AppResources.SuccessTitle)],
571 ServiceRef.Localizer[nameof(AppResources.IdCopiedSuccessfully)]);
572 }
573 else
574 {
575 await Clipboard.SetTextAsync(Label);
576 await ServiceRef.UiService.DisplayAlert(
577 ServiceRef.Localizer[nameof(AppResources.SuccessTitle)],
578 ServiceRef.Localizer[nameof(AppResources.TagValueCopiedToClipboard)]);
579 }
580 }
581 }
582 catch (Exception ex)
583 {
584 ServiceRef.LogService.LogException(ex);
585 await ServiceRef.UiService.DisplayException(ex);
586 }
587 }
588 }
589}
The Application class, representing an instance of the Neuro-Access app.
Definition: App.xaml.cs:69
static Task< bool > AuthenticateUser(AuthenticationPurpose Purpose, bool Force=false)
Authenticates the user using the configured authentication method.
Definition: App.xaml.cs:981
static readonly TimeSpan XmppInit
XMPP Init timeout
Definition: Constants.cs:576
static string CreateIdUri(string id)
Generates a IoT ID Uri form the specified id.
Definition: Constants.cs:198
const string IotId
The IoT ID URI Scheme (iotid)
Definition: Constants.cs:99
const string PersonalNumber
Personal number
Definition: Constants.cs:284
const string OrgAddress2
Organization Address line 2
Definition: Constants.cs:364
const string OrgArea
Organization Area
Definition: Constants.cs:369
const string OrgRegion
Organization Region
Definition: Constants.cs:384
const string Nationality
Nationality
Definition: Constants.cs:324
const string BirthYear
Birth Year
Definition: Constants.cs:344
const string OrgCity
Organization City
Definition: Constants.cs:374
const string OrgRole
Organization Role
Definition: Constants.cs:399
const string Phone
Phone number
Definition: Constants.cs:414
const string EMail
e-Mail address
Definition: Constants.cs:419
const string OrgZipCode
Organization Zip Code
Definition: Constants.cs:379
const string MiddleNames
Middle names
Definition: Constants.cs:274
const string OrgCountry
Organization Country
Definition: Constants.cs:389
const string OrgDepartment
Organization Department
Definition: Constants.cs:394
const string Address2
Address line 2
Definition: Constants.cs:294
const string Domain
Domain name.
Definition: Constants.cs:424
const string OrgAddress
Organization Address line 1
Definition: Constants.cs:359
const string Address
Address line 1
Definition: Constants.cs:289
const string LastNames
Last names
Definition: Constants.cs:279
const string OrgNumber
Organization number
Definition: Constants.cs:354
const string BirthMonth
Birth Month
Definition: Constants.cs:339
const string FirstName
First name
Definition: Constants.cs:269
const string OrgName
Organization name
Definition: Constants.cs:349
A set of never changing property constants and helpful values.
Definition: Constants.cs:7
const string NotAvailableValue
A generic "no value available" string.
Definition: Constants.cs:11
Contains information about a contact.
Definition: ContactInfo.cs:21
static string GetFullName(LegalIdentity? Identity)
Gets the full name of a person.
Definition: ContactInfo.cs:577
Base class that references services in the app.
Definition: ServiceRef.cs:31
static ILogService LogService
Log service.
Definition: ServiceRef.cs:91
static INetworkService NetworkService
Network service.
Definition: ServiceRef.cs:103
static IUiService UiService
Service serializing and managing UI-related tasks.
Definition: ServiceRef.cs:55
static IStringLocalizer Localizer
Localization service
Definition: ServiceRef.cs:235
static IXmppService XmppService
The XMPP service for XMPP communication.
Definition: ServiceRef.cs:67
virtual async Task GoBack()
Method called when user wants to navigate to the previous screen.
Holds navigation parameters specific to views displaying a petition of a signature.
The view model to bind to when displaying petitioning of a signature in a view or page.
override async Task OnDispose()
Method called when the view is disposed, and will not be used more. Use this method to unregister eve...
ObservableCollection< Photo > Photos
The list of photos related to the identity being petitioned.
PetitionSignatureViewModel(PetitionSignatureNavigationArgs? Args)
Creates a new instance of the PetitionSignatureViewModel class.
override Task XmppService_ConnectionStateChanged(object? Sender, XmppState NewState)
Listens to connection state changes from the XMPP server.
override async Task OnInitialize()
Method called when view is initialized for the first time. Use this method to implement registration ...
A view model that holds the XMPP state.
void RemoveQrCode()
Removes the QR-code
void GenerateQrCode(string Uri)
Generates a QR-code
Contains a reference to an attachment assigned to a legal object.
Definition: Attachment.cs:9
Abstract base class of signatures
Definition: Signature.cs:10
class Photo(byte[] Binary, int Rotation)
Class containing information about a photo.
Definition: Photo.cs:8
AuthenticationPurpose
Purpose for requesting the user to authenticate itself.
IdentityState
Lists recognized legal identity states.
SignWith
Options on what keys to use when signing data.
Definition: Enumerations.cs:84
XmppState
State of XMPP connection.
Definition: XmppState.cs:7