profile-pane 3.1.2-e3347eef → 3.1.2-f880e98a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,5 +2,6 @@ import { DataBrowserContext } from 'pane-registry';
2
2
  import { AddressBooksData, ContactData } from './contactsTypes';
3
3
  import ContactsModuleRdfLib from '@solid-data-modules/contacts-rdflib';
4
4
  export declare const createAddressBookUriSelectorDialog: (context: DataBrowserContext, contactsModule: ContactsModuleRdfLib, contactData: ContactData, addressBooksData: AddressBooksData) => HTMLDialogElement;
5
+ export declare const handleContactExistsByName: (context: DataBrowserContext, addressBooksData: AddressBooksData, contactData: ContactData, contactExistsByNameUri: string, fromRegisteredAddressBook: boolean) => Boolean;
5
6
  export declare function getButtonContainer(context: DataBrowserContext): HTMLDivElement;
6
7
  //# sourceMappingURL=ContactsCard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ContactsCard.d.ts","sourceRoot":"","sources":["../src/ContactsCard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,EAAsB,gBAAgB,EAAE,WAAW,EAAa,MAAM,iBAAiB,CAAA;AAC9F,OAAO,oBAAoB,MAAM,qCAAqC,CAAA;AAQtE,eAAO,MAAM,kCAAkC,GAAI,SAAS,kBAAkB,EAC5E,gBAAgB,oBAAoB,EACpC,aAAa,WAAW,EACxB,kBAAkB,gBAAgB,KACjC,iBAuCF,CAAA;AAw0BD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,kBAAkB,GAC1B,cAAc,CAIhB"}
1
+ {"version":3,"file":"ContactsCard.d.ts","sourceRoot":"","sources":["../src/ContactsCard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,EAAsB,gBAAgB,EAAE,WAAW,EAAa,MAAM,iBAAiB,CAAA;AAC9F,OAAO,oBAAoB,MAAM,qCAAqC,CAAA;AAUtE,eAAO,MAAM,kCAAkC,GAAI,SAAS,kBAAkB,EAC5E,gBAAgB,oBAAoB,EACpC,aAAa,WAAW,EACxB,kBAAkB,gBAAgB,KACjC,iBAuCF,CAAA;AAgvBD,eAAO,MAAM,yBAAyB,GACpC,SAAS,kBAAkB,EAC3B,kBAAkB,gBAAgB,EAClC,aAAa,WAAW,EACxB,wBAAwB,MAAM,EAC9B,2BAA2B,OAAO,KACjC,OAkEF,CAAA;AAuDD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,kBAAkB,GAC1B,cAAc,CAIhB"}
@@ -5,10 +5,13 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.createAddressBookUriSelectorDialog = void 0;
7
7
  exports.getButtonContainer = getButtonContainer;
8
+ exports.handleContactExistsByName = void 0;
8
9
  var _contactsHelpers = require("./contactsHelpers");
10
+ var _contactsPane = require("contacts-pane");
9
11
  var _buttonsHelper = require("./buttonsHelper");
10
12
  var _texts = require("./texts");
11
13
  var _contactsErrors = require("./contactsErrors");
14
+ var _rdflib = require("rdflib");
12
15
  const CONTACTS_POPUP_OVERLAY_ID = 'contacts-popup-overlay';
13
16
  const CONTACTS_OVERLAY_ACTIVE_CLASS = 'contactsOverlayActive';
14
17
  const createAddressBookUriSelectorDialog = (context, contactsModule, contactData, addressBooksData) => {
@@ -269,8 +272,8 @@ const createNewContactCreationButton = (context, contactsModule, addressBooksDat
269
272
  const setButtonOnClickHandler = async event => {
270
273
  event.preventDefault();
271
274
  const contactExistsByWebID = (0, _contactsHelpers.checkIfContactExistsByWebID)(addressBooksData, contactData.webID);
272
- const contactExistsByName = (0, _contactsHelpers.checkIfContactExistsByName)(addressBooksData, contactData.name);
273
- const contactExistsHandled = handleContactExists(context, contactsModule, addressBooksData, contactData, contactExistsByWebID, contactExistsByName);
275
+ const contactExistsByNameUri = (0, _contactsHelpers.checkIfContactExistsByName)(addressBooksData, contactData.name);
276
+ const contactExistsHandled = handleContactExistsFromNonRegisteredAddressBook(context, addressBooksData, contactData, contactExistsByWebID, contactExistsByNameUri);
274
277
  if (contactExistsHandled) return;
275
278
  let selectedAddressBookUri = null;
276
279
  let selectedGroupUris = [];
@@ -288,7 +291,7 @@ const createNewContactCreationButton = (context, contactsModule, addressBooksDat
288
291
  groupUris: selectedGroupUris
289
292
  };
290
293
  try {
291
- const contactUri = await (0, _contactsHelpers.createContactInAddressBook)(context, contactsModule, addressBooksData, contactData, selectedAddressBookUris);
294
+ const contactUri = await (0, _contactsHelpers.createContactInAddressBook)(context, contactsModule, contactData, selectedAddressBookUris);
292
295
  finalizeContactEntry(context, addressBooksData, contactData, contactUri);
293
296
  } catch (error) {
294
297
  (0, _contactsErrors.addErrorToErrorDisplay)(context, `${_texts.errorContactCreation}\n${error}`);
@@ -368,31 +371,35 @@ const createNewAddressBookForm = (context, addressBooksData, contactsModule, con
368
371
  const newAddressBookEventListener = async event => {
369
372
  event.preventDefault();
370
373
  let enteredAddressBookUri = null;
371
- let newGroupUri = null;
374
+ let newGroupNode = null;
372
375
  const addressNameField = context.dom.querySelector('#addressBookNameInput');
373
376
 
374
377
  // @ts-ignore
375
- const enteredAddressName = addressNameField.value;
378
+ const enteredAddressName = sanitizeInput(addressNameField.value);
379
+ // @ts-ignore
380
+ addressNameField.value = enteredAddressName;
376
381
  const addressContainerField = context.dom.querySelector('#addressBookContainerInput');
377
382
 
378
383
  // @ts-ignore
379
- const enteredAddressContainer = addressContainerField.value;
384
+ const enteredAddressContainer = sanitizeInput(addressContainerField.value);
385
+ // @ts-ignore
386
+ addressContainerField.value = enteredAddressContainer;
380
387
  const groupNameField = context.dom.querySelector('#groupNameInput');
381
388
  // @ts-ignore
382
- const enteredGroupName = groupNameField.value;
389
+ const enteredGroupName = sanitizeInput(groupNameField.value);
390
+ // @ts-ignore
391
+ groupNameField.value = enteredGroupName;
383
392
  if (enteredAddressName) {
384
393
  // add addressbook first
385
394
  try {
386
395
  enteredAddressBookUri = await (0, _contactsHelpers.handleAddressBookCreation)(context, enteredAddressContainer, enteredAddressName);
387
396
  const books = await (0, _contactsHelpers.addANewAddressBookUriToAddressBooks)(context, contactsModule, addressBooksData, enteredAddressBookUri);
388
397
  if (enteredGroupName) {
389
- newGroupUri = await contactsModule.createNewGroup({
390
- addressBookUri: enteredAddressBookUri,
391
- groupName: enteredGroupName
392
- });
398
+ const selectedAddressBookNode = new _rdflib.NamedNode(enteredAddressBookUri);
399
+ newGroupNode = await (0, _contactsPane.saveNewGroup)(selectedAddressBookNode, enteredGroupName);
393
400
  const groupAdded = await (0, _contactsHelpers.addGroupToAddressBookData)(addressBooksData, enteredAddressBookUri, {
394
401
  name: enteredGroupName,
395
- uri: newGroupUri
402
+ uri: newGroupNode.value
396
403
  });
397
404
  if (!groupAdded) {
398
405
  (0, _contactsErrors.addErrorToErrorDisplay)(context, _texts.errorGroupCreation);
@@ -416,7 +423,7 @@ const createNewAddressBookForm = (context, addressBooksData, contactsModule, con
416
423
  const groupCreationButton = context.dom.getElementById('contacts-create-group-button');
417
424
  groupCreationButton.remove();
418
425
  groupListDiv.appendChild(createGroupButton(context, {
419
- uri: newGroupUri,
426
+ uri: newGroupNode.value,
420
427
  name: enteredGroupName
421
428
  }));
422
429
  groupListDiv.appendChild(groupCreationButton);
@@ -465,6 +472,10 @@ const createNewAddressBookForm = (context, addressBooksData, contactsModule, con
465
472
  groupNameInputBox.placeholder = 'New group name';
466
473
  groupNameInputBox.classList.add('input', 'contactsGroupInput');
467
474
  groupNameInputBox.required = true;
475
+ const validationMessage = createValidationMessage(context);
476
+ attachSanitizingValidation(addressBookNameInputBox, validationMessage);
477
+ attachSanitizingValidation(addressBookContainerInputBox, validationMessage);
478
+ attachSanitizingValidation(groupNameInputBox, validationMessage);
468
479
  const submitButton = context.dom.createElement('button');
469
480
  submitButton.setAttribute('id', 'submit-addressbook');
470
481
  submitButton.setAttribute('role', 'button');
@@ -482,11 +493,13 @@ const createNewAddressBookForm = (context, addressBooksData, contactsModule, con
482
493
  newAddressBookForm.appendChild(addressBookContainerInputBox);
483
494
  newAddressBookForm.appendChild(groupNameLabel);
484
495
  newAddressBookForm.appendChild(groupNameInputBox);
496
+ newAddressBookForm.appendChild(validationMessage);
485
497
  newAddressBookForm.appendChild(submitButton);
486
498
  newAddressBookForm.addEventListener('submit', newAddressBookEventListener);
487
499
  return newAddressBookForm;
488
500
  };
489
501
  const createCloseButton = (context, element, specialClass) => {
502
+ const buttonID = `${element.id}-close-button`;
490
503
  const setButtonOnClickHandler = event => {
491
504
  event.preventDefault();
492
505
  if (element) {
@@ -499,7 +512,7 @@ const createCloseButton = (context, element, specialClass) => {
499
512
  }
500
513
  };
501
514
  const closeButton = context.dom.createElement('button');
502
- closeButton.setAttribute('id', 'close-addressbook');
515
+ closeButton.setAttribute('id', buttonID);
503
516
  closeButton.setAttribute('role', 'button');
504
517
  closeButton.setAttribute('type', 'button');
505
518
  const ariaLabel = specialClass === 'contactsCloseButton' ? 'Close contacts dialog' : 'Close dialog';
@@ -520,7 +533,9 @@ const createGroupNameForm = (context, contactsModule, addressBooksData, contactD
520
533
  });
521
534
  const groupNameField = context.dom.querySelector('#groupNameInput');
522
535
  // @ts-ignore
523
- const enteredGroupName = groupNameField.value;
536
+ const enteredGroupName = sanitizeInput(groupNameField.value);
537
+ // @ts-ignore
538
+ groupNameField.value = enteredGroupName;
524
539
  if (!selectedAddressBookUri) {
525
540
  (0, _contactsErrors.addErrorToErrorDisplay)(context, _texts.errorNotExistsAddressBookUri);
526
541
  return;
@@ -528,13 +543,11 @@ const createGroupNameForm = (context, contactsModule, addressBooksData, contactD
528
543
  if (enteredGroupName) {
529
544
  // add group first
530
545
  try {
531
- const newGroupUri = await contactsModule.createNewGroup({
532
- addressBookUri: selectedAddressBookUri,
533
- groupName: enteredGroupName
534
- });
546
+ const selectedAddressBookNode = new _rdflib.NamedNode(selectedAddressBookUri);
547
+ const newGroupNode = await (0, _contactsPane.saveNewGroup)(selectedAddressBookNode, enteredGroupName);
535
548
  const newGroup = {
536
549
  name: enteredGroupName,
537
- uri: newGroupUri
550
+ uri: newGroupNode.value
538
551
  };
539
552
  const wasUpdated = (0, _contactsHelpers.addGroupToAddressBookData)(addressBooksData, selectedAddressBookUri, newGroup);
540
553
  if (!wasUpdated) {
@@ -569,10 +582,13 @@ const createGroupNameForm = (context, contactsModule, addressBooksData, contactD
569
582
  groupNameInputBox.id = 'groupNameInput';
570
583
  groupNameInputBox.placeholder = 'New group name';
571
584
  groupNameInputBox.classList.add('input', 'contactsGroupInput');
585
+ const validationMessage = createValidationMessage(context);
586
+ attachSanitizingValidation(groupNameInputBox, validationMessage);
572
587
  const submitButton = createAddGroupButton(context, newGroupForm);
573
588
  const closeButton = createCloseButton(context, newGroupForm, 'contactsGroupCreationCloseButton');
574
589
  newGroupForm.appendChild(groupNameLabel);
575
590
  newGroupForm.appendChild(groupNameInputBox);
591
+ newGroupForm.appendChild(validationMessage);
576
592
  newGroupForm.appendChild(submitButton);
577
593
  newGroupForm.appendChild(closeButton);
578
594
  return newGroupForm;
@@ -593,75 +609,87 @@ const createAddGroupButton = (context, form) => {
593
609
  button.addEventListener('click', setButtonOnClickHandler);
594
610
  return button;
595
611
  };
596
- const handleContactExists = (context, contactsModule, addressBooksData, contactData, contactExistsByWebID, contactExistsByName) => {
612
+ const handleContactExistsFromNonRegisteredAddressBook = (context, addressBooksData, contactData, contactExistsByWebID, contactExistsByNameUri) => {
597
613
  if (contactExistsByWebID) {
598
614
  (0, _contactsErrors.addErrorToErrorDisplay)(context, _texts.contactExistsMessage);
599
615
  return true;
600
- } else if (contactExistsByName) {
601
- // need to disable and possibly grey out the dialog
602
- const selectorDialog = context.dom.getElementById('contacts-selector-dialog');
603
- const contactExistsDiv = context.dom.createElement('div');
604
- contactExistsDiv.setAttribute('role', 'alert');
605
- contactExistsDiv.setAttribute('aria-live', 'assertive');
606
- contactExistsDiv.setAttribute('tabindex', '0');
607
- contactExistsDiv.setAttribute('aria-label', 'Alert message indicating that the contact already exists');
608
- contactExistsDiv.setAttribute('id', 'contacts-contact-exists');
609
- contactExistsDiv.classList.add('contactsContactExistsAlert');
610
- contactExistsDiv.innerHTML = `${contactData.name} already exists. \n Do you want to add their WebID?`;
611
- const confirmButton = context.dom.createElement('button');
612
- confirmButton.setAttribute('id', 'contacts-confirm-add-webid-button');
613
- confirmButton.setAttribute('role', 'button');
614
- confirmButton.setAttribute('type', 'button');
615
- confirmButton.setAttribute('aria-label', 'Confirm adding the contact webID to the existing contact');
616
- confirmButton.setAttribute('tabindex', '0');
617
- confirmButton.classList.add('contactsConfirmButton');
618
- confirmButton.innerHTML = 'Yes';
619
- confirmButton.addEventListener('click', async event => {
620
- event.preventDefault();
621
- await (0, _contactsHelpers.addWebIDToExistingContact)(context, contactsModule, addressBooksData, contactData.webID, contactExistsByName);
622
- finalizeContactEntry(context, addressBooksData, contactData, addressBooksData.contactWebIDs.get(contactData.webID));
623
- (0, _contactsHelpers.refreshButton)(context, addressBooksData, contactData);
624
- });
625
- const cancelButton = context.dom.createElement('button');
626
- cancelButton.setAttribute('id', 'contacts-cancel-add-webid-button');
627
- cancelButton.setAttribute('role', 'button');
628
- cancelButton.setAttribute('type', 'button');
629
- cancelButton.setAttribute('aria-label', 'Cancel adding the contact webID to the existing contact');
630
- cancelButton.setAttribute('tabindex', '0');
631
- cancelButton.classList.add('contactsCancelButton');
632
- cancelButton.innerHTML = 'No';
633
- cancelButton.addEventListener('click', event => {
634
- event.preventDefault();
635
- selectorDialog.remove();
636
- (0, _buttonsHelper.complain)(getButtonContainer(context), context, 'Contact was not added');
637
- setTimeout(() => {
638
- (0, _buttonsHelper.clearPreviousMessage)(getButtonContainer(context));
639
- }, 2000);
640
- (0, _contactsHelpers.refreshButton)(context, addressBooksData, contactData);
641
- });
642
- const actionsDiv = context.dom.createElement('div');
643
- actionsDiv.setAttribute('id', 'contacts-contact-exists-actions');
644
- actionsDiv.setAttribute('role', 'group');
645
- actionsDiv.setAttribute('aria-label', 'Actions for existing contact alert');
646
- actionsDiv.setAttribute('tabindex', '0');
647
- actionsDiv.classList.add('contactsContactExistsActions');
648
- actionsDiv.appendChild(confirmButton);
649
- actionsDiv.appendChild(cancelButton);
650
- contactExistsDiv.appendChild(actionsDiv);
651
- showPopupOverlay(context);
652
- selectorDialog.appendChild(contactExistsDiv);
653
- return true;
616
+ } else if (contactExistsByNameUri) {
617
+ const fromRegisteredAddressBook = false;
618
+ const handled = handleContactExistsByName(context, addressBooksData, contactData, contactExistsByNameUri, fromRegisteredAddressBook);
619
+ return handled;
654
620
  }
655
621
  return false;
656
622
  };
623
+ const handleContactExistsByName = (context, addressBooksData, contactData, contactExistsByNameUri, fromRegisteredAddressBook) => {
624
+ const selectorDialog = context.dom.getElementById('contacts-selector-dialog');
625
+ const buttonContainer = getButtonContainer(context);
626
+ const contactExistsDiv = context.dom.createElement('div');
627
+ contactExistsDiv.setAttribute('role', 'alert');
628
+ contactExistsDiv.setAttribute('aria-live', 'assertive');
629
+ contactExistsDiv.setAttribute('tabindex', '0');
630
+ contactExistsDiv.setAttribute('aria-label', 'Alert message indicating that the contact already exists');
631
+ contactExistsDiv.setAttribute('id', 'contacts-contact-exists');
632
+ contactExistsDiv.classList.add('contactsContactExistsAlert');
633
+ contactExistsDiv.innerHTML = `${contactData.name} already exists. \n Do you want to add their WebID?`;
634
+ const confirmButton = context.dom.createElement('button');
635
+ confirmButton.setAttribute('id', 'contacts-confirm-add-webid-button');
636
+ confirmButton.setAttribute('role', 'button');
637
+ confirmButton.setAttribute('type', 'button');
638
+ confirmButton.setAttribute('aria-label', 'Confirm adding the contact webID to the existing contact');
639
+ confirmButton.setAttribute('tabindex', '0');
640
+ confirmButton.classList.add('contactsConfirmButton');
641
+ confirmButton.innerHTML = 'Yes';
642
+ confirmButton.addEventListener('click', async event => {
643
+ event.preventDefault();
644
+ await (0, _contactsHelpers.addWebIDToExistingContact)(context, contactData, contactExistsByNameUri);
645
+ contactExistsDiv.remove();
646
+ finalizeContactEntry(context, addressBooksData, contactData, addressBooksData.contactWebIDs.get(contactData.webID));
647
+ (0, _contactsHelpers.refreshButton)(context, addressBooksData, contactData);
648
+ });
649
+ const cancelButton = context.dom.createElement('button');
650
+ cancelButton.setAttribute('id', 'contacts-cancel-add-webid-button');
651
+ cancelButton.setAttribute('role', 'button');
652
+ cancelButton.setAttribute('type', 'button');
653
+ cancelButton.setAttribute('aria-label', 'Cancel adding the contact webID to the existing contact');
654
+ cancelButton.setAttribute('tabindex', '0');
655
+ cancelButton.classList.add('contactsCancelButton');
656
+ cancelButton.innerHTML = 'No';
657
+ cancelButton.addEventListener('click', event => {
658
+ event.preventDefault();
659
+ if (!fromRegisteredAddressBook) selectorDialog.remove();
660
+ contactExistsDiv.remove();
661
+ (0, _buttonsHelper.complain)(getButtonContainer(context), context, 'Contact was not added');
662
+ setTimeout(() => {
663
+ (0, _buttonsHelper.clearPreviousMessage)(getButtonContainer(context));
664
+ }, 2000);
665
+ (0, _contactsHelpers.refreshButton)(context, addressBooksData, contactData);
666
+ });
667
+ const actionsDiv = context.dom.createElement('div');
668
+ actionsDiv.setAttribute('id', 'contacts-contact-exists-actions');
669
+ actionsDiv.setAttribute('role', 'group');
670
+ actionsDiv.setAttribute('aria-label', 'Actions for existing contact alert');
671
+ actionsDiv.setAttribute('tabindex', '0');
672
+ actionsDiv.classList.add('contactsContactExistsActions');
673
+ actionsDiv.appendChild(confirmButton);
674
+ actionsDiv.appendChild(cancelButton);
675
+ contactExistsDiv.appendChild(actionsDiv);
676
+ showPopupOverlay(context);
677
+ if (fromRegisteredAddressBook) {
678
+ buttonContainer.appendChild(contactExistsDiv);
679
+ } else {
680
+ selectorDialog.appendChild(contactExistsDiv);
681
+ }
682
+ return true;
683
+ };
684
+ exports.handleContactExistsByName = handleContactExistsByName;
657
685
  const finalizeContactEntry = (context, addressBooksData, contactData, contactUri) => {
658
686
  addressBooksData.contactWebIDs.set(contactData.webID, contactUri);
659
687
  const selectorDialog = context.dom.getElementById('contacts-selector-dialog');
660
- selectorDialog.remove();
688
+ if (selectorDialog) selectorDialog.remove();
661
689
  const buttonContainer = getButtonContainer(context);
662
690
  (0, _buttonsHelper.mention)(buttonContainer, _texts.contactWasAddedSuccesMessage);
663
- const button = context.dom.getElementById('add-to-contacts-button');
664
- button.removeAttribute('disabled');
691
+ // const button = context.dom.getElementById('add-to-contacts-button')
692
+ // button.removeAttribute('disabled')
665
693
  setTimeout(() => {
666
694
  (0, _buttonsHelper.clearPreviousMessage)(buttonContainer);
667
695
  }, 2000);
@@ -718,4 +746,29 @@ const removePopupOverlayIfNoPopup = context => {
718
746
  const overlay = selectorDialog.querySelector(`#${CONTACTS_POPUP_OVERLAY_ID}`);
719
747
  if (overlay) overlay.remove();
720
748
  selectorDialog.classList.remove(CONTACTS_OVERLAY_ACTIVE_CLASS);
721
- };
749
+ };
750
+ /* Sanitization and validation */
751
+ function sanitizeInput(input) {
752
+ return (input || '').replace(/[^a-zA-Z0-9 ]+/g, '').replace(/\s+/g, ' ').trim();
753
+ }
754
+ function attachSanitizingValidation(input, feedbackElement) {
755
+ input.addEventListener('input', () => {
756
+ const rawValue = input.value;
757
+ const sanitizedValue = sanitizeInput(rawValue);
758
+ if (rawValue !== sanitizedValue) {
759
+ input.value = sanitizedValue;
760
+ input.setAttribute('aria-invalid', 'true');
761
+ feedbackElement.textContent = 'Only letters, numbers, and spaces are allowed.';
762
+ return;
763
+ }
764
+ input.removeAttribute('aria-invalid');
765
+ feedbackElement.textContent = '';
766
+ });
767
+ }
768
+ function createValidationMessage(context) {
769
+ const validationMessage = context.dom.createElement('p');
770
+ validationMessage.setAttribute('role', 'status');
771
+ validationMessage.setAttribute('aria-live', 'polite');
772
+ validationMessage.classList.add('contactsInputValidationMessage');
773
+ return validationMessage;
774
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"addMeToYourContacts.d.ts","sourceRoot":"","sources":["../src/addMeToYourContacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,cAAc,EAAE,MAAM,UAAU,CAAA;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,EAAa,SAAS,EAAE,MAAM,QAAQ,CAAA;AAM7C,OAAO,EAAE,gBAAgB,EAAe,MAAM,iBAAiB,CAAA;AAI/D,OAAO,0BAA0B,CAAA;AACjC,OAAO,oBAAoB,MAAM,qCAAqC,CAAA;AAKtE,QAAA,MAAM,sBAAsB,GAC1B,SAAS,SAAS,EAClB,SAAS,kBAAkB,KAC1B,OAAO,CAAC,cAAc,CAmBxB,CAAA;AAED,QAAA,MAAM,+BAA+B,GACnC,SAAS,SAAS,EAClB,SAAS,kBAAkB,KAC1B,OAAO,CAAC,iBAAiB,CA2D3B,CAAA;AAED,iBAAe,cAAc,CAC3B,OAAO,EAAE,SAAS,EAClB,OAAO,EAAE,kBAAkB,EAC3B,cAAc,EAAE,oBAAoB,EACpC,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED,OAAO,EACL,sBAAsB,EACtB,+BAA+B,EAC/B,cAAc,EACf,CAAA"}
1
+ {"version":3,"file":"addMeToYourContacts.d.ts","sourceRoot":"","sources":["../src/addMeToYourContacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,cAAc,EAAE,MAAM,UAAU,CAAA;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,EAAa,SAAS,EAAE,MAAM,QAAQ,CAAA;AAM7C,OAAO,EAAE,gBAAgB,EAAe,MAAM,iBAAiB,CAAA;AAK/D,OAAO,0BAA0B,CAAA;AACjC,OAAO,oBAAoB,MAAM,qCAAqC,CAAA;AAMtE,QAAA,MAAM,sBAAsB,GAC1B,SAAS,SAAS,EAClB,SAAS,kBAAkB,KAC1B,OAAO,CAAC,cAAc,CAmBxB,CAAA;AAED,QAAA,MAAM,+BAA+B,GACnC,SAAS,SAAS,EAClB,SAAS,kBAAkB,KAC1B,OAAO,CAAC,iBAAiB,CA2D3B,CAAA;AAED,iBAAe,cAAc,CAC3B,OAAO,EAAE,SAAS,EAClB,OAAO,EAAE,kBAAkB,EAC3B,cAAc,EAAE,oBAAoB,EACpC,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED,OAAO,EACL,sBAAsB,EACtB,+BAA+B,EAC/B,cAAc,EACf,CAAA"}
@@ -14,6 +14,7 @@ var _texts = require("./texts");
14
14
  require("./styles/ProfileCard.css");
15
15
  var _contactsRdflib = _interopRequireDefault(require("@solid-data-modules/contacts-rdflib"));
16
16
  var _contactsErrors = require("./contactsErrors");
17
+ var _ContactsCard = require("./ContactsCard");
17
18
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
18
19
  let buttonContainer = document.createElement('section');
19
20
  const addMeToYourContactsDiv = async (subject, context) => {
@@ -104,7 +105,9 @@ async function saveNewContact(subject, context, contactsModule, addressBooksData
104
105
  const contactData = await (0, _contactsHelpers.getContactData)(store, subject);
105
106
  const contactExistsByNameUri = (0, _contactsHelpers.checkIfContactExistsByName)(addressBooksData, contactData.name);
106
107
  if (contactExistsByNameUri) {
107
- await (0, _contactsHelpers.addWebIDToExistingContact)(context, contactsModule, addressBooksData, contactData.webID, contactExistsByNameUri);
108
+ const fromRegisteredAddressBook = true;
109
+ const handled = (0, _ContactsCard.handleContactExistsByName)(context, addressBooksData, contactData, contactExistsByNameUri, fromRegisteredAddressBook);
110
+ if (!handled) (0, _contactsErrors.addErrorToErrorDisplay)(context, _texts.errorAddingContactWebIDToAddressBook);
108
111
  } else {
109
112
  await (0, _contactsHelpers.addContactToAddressBook)(context, contactsModule, contactData, addressBooksData, buttonContainer);
110
113
  }
@@ -10,13 +10,13 @@ declare function addANewAddressBookUriToAddressBooks(context: DataBrowserContext
10
10
  addressBooksData: AddressBooksData;
11
11
  addressBook: AddressBookDetails;
12
12
  }>;
13
- declare function createContactInAddressBook(context: DataBrowserContext, contactsModule: ContactsModuleRdfLib, addressBooksData: AddressBooksData, contactData: ContactData, selectedAddressBookUris: SelectedAddressBookUris): Promise<string>;
13
+ declare function createContactInAddressBook(context: DataBrowserContext, contactsModule: ContactsModuleRdfLib, contactData: ContactData, selectedAddressBookUris: SelectedAddressBookUris): Promise<string>;
14
14
  declare function addAddressToTypeIndex(context: DataBrowserContext, typeOfIndex: string, addressBookUri: string): Promise<boolean>;
15
15
  declare function updateAddressBookName(context: DataBrowserContext, addressBookUri: string, newName: string): Promise<void>;
16
16
  declare function refreshButton(context: DataBrowserContext, addressBooksData: AddressBooksData, contactData: ContactData): void;
17
17
  declare function checkIfContactExistsByWebID(addressBooksData: AddressBooksData, subjectUri: string): boolean;
18
18
  declare function checkIfContactExistsByName(addressBooksData: AddressBooksData, name: string): string | null;
19
- declare function addWebIDToExistingContact(context: DataBrowserContext, contactsModule: ContactsModuleRdfLib, addressBooksData: AddressBooksData, webID: string, contactUri: string): Promise<void>;
19
+ declare function addWebIDToExistingContact(context: DataBrowserContext, contactData: ContactData, contactUri: string): Promise<void>;
20
20
  declare function addGroupToAddressBookData(addressBooksData: AddressBooksData, addressBookUri: string, group: GroupData): boolean;
21
21
  declare function handleAddressBookCreation(dataBrowserContext: DataBrowserContext, containerName: string, enteredAddressName: string): Promise<string>;
22
22
  export { getAddressBooksData, getContactData, addContactToAddressBook, createContactInAddressBook, addAddressToTypeIndex, refreshButton, checkIfContactExistsByWebID, checkIfContactExistsByName, addWebIDToExistingContact, addANewAddressBookUriToAddressBooks, addGroupToAddressBookData, updateAddressBookName, handleAddressBookCreation };
@@ -1 +1 @@
1
- {"version":3,"file":"contactsHelpers.d.ts","sourceRoot":"","sources":["../src/contactsHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAoB,MAAM,QAAQ,CAAA;AAE/D,OAAO,oBAAoB,MAAM,qCAAqC,CAAA;AAEtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,2BAA2B,CAAA;AAElC,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,EAAgB,SAAS,EAAgB,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAMnJ,iBAAe,uBAAuB,CACpC,OAAO,EAAE,kBAAkB,EAC3B,cAAc,EAAE,oBAAoB,EACpC,WAAW,EAAE,WAAW,EACxB,gBAAgB,EAAE,gBAAgB,EAClC,SAAS,EAAE,cAAc,iBAM1B;AAgHD,iBAAe,mBAAmB,CAChC,OAAO,EAAE,kBAAkB,EAC3B,aAAa,EAAE,oBAAoB,GAClC,OAAO,CAAC,gBAAgB,CAAC,CAY3B;AAkBD,iBAAe,cAAc,CAC3B,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,WAAW,CAAC,CA8BtB;AAED,iBAAe,mCAAmC,CAChD,OAAO,EAAC,kBAAkB,EAC1B,cAAc,EAAE,oBAAoB,EACpC,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,MAAM,GAC5B,OAAO,CAAC;IAAE,gBAAgB,EAAE,gBAAgB,CAAC;IAAC,WAAW,EAAE,kBAAkB,CAAA;CAAE,CAAC,CA2BlF;AAED,iBAAe,0BAA0B,CACvC,OAAO,EAAE,kBAAkB,EAC3B,cAAc,EAAE,oBAAoB,EACpC,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,EAAE,WAAW,EACxB,uBAAuB,EAAE,uBAAuB,GAC/C,OAAO,CAAC,MAAM,CAAC,CAwBjB;AAqFD,iBAAe,qBAAqB,CAClC,OAAO,EAAE,kBAAkB,EAC3B,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC,CAuBlB;AAED,iBAAe,qBAAqB,CAClC,OAAO,EAAE,kBAAkB,EAC3B,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,iBA0BhB;AAED,iBAAS,aAAa,CACpB,OAAO,EAAE,kBAAkB,EAC3B,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,EAAE,WAAW,QAuBvB;AAEH,iBAAS,2BAA2B,CAClC,gBAAgB,EAAE,gBAAgB,EAClC,UAAU,EAAE,MAAM,GACjB,OAAO,CAGT;AAED,iBAAS,0BAA0B,CACjC,gBAAgB,EAAE,gBAAgB,EAClC,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,IAAI,CAYf;AAED,iBAAe,yBAAyB,CACtC,OAAO,EAAE,kBAAkB,EAC3B,cAAc,EAAE,oBAAoB,EACpC,gBAAgB,EAAE,gBAAgB,EAClC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,iBASnB;AA6CD,iBAAS,yBAAyB,CAChC,gBAAgB,EAAE,gBAAgB,EAClC,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,SAAS,GACf,OAAO,CA0BT;AAED,iBAAe,yBAAyB,CACtC,kBAAkB,EAAE,kBAAkB,EACtC,aAAa,EAAE,MAAM,EACrB,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC,MAAM,CAAC,CAsCjB;AAED,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,EACrB,aAAa,EACb,2BAA2B,EAC3B,0BAA0B,EAC1B,yBAAyB,EACzB,mCAAmC,EACnC,yBAAyB,EACzB,qBAAqB,EACrB,yBAAyB,EAC1B,CAAA"}
1
+ {"version":3,"file":"contactsHelpers.d.ts","sourceRoot":"","sources":["../src/contactsHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAoB,MAAM,QAAQ,CAAA;AAE/D,OAAO,oBAAoB,MAAM,qCAAqC,CAAA;AAEtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,2BAA2B,CAAA;AAElC,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,EAAgB,SAAS,EAAgB,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAMnJ,iBAAe,uBAAuB,CACpC,OAAO,EAAE,kBAAkB,EAC3B,cAAc,EAAE,oBAAoB,EACpC,WAAW,EAAE,WAAW,EACxB,gBAAgB,EAAE,gBAAgB,EAClC,SAAS,EAAE,cAAc,iBAM1B;AAgHD,iBAAe,mBAAmB,CAChC,OAAO,EAAE,kBAAkB,EAC3B,aAAa,EAAE,oBAAoB,GAClC,OAAO,CAAC,gBAAgB,CAAC,CAY3B;AAkBD,iBAAe,cAAc,CAC3B,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,WAAW,CAAC,CA8BtB;AAED,iBAAe,mCAAmC,CAChD,OAAO,EAAC,kBAAkB,EAC1B,cAAc,EAAE,oBAAoB,EACpC,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,MAAM,GAC5B,OAAO,CAAC;IAAE,gBAAgB,EAAE,gBAAgB,CAAC;IAAC,WAAW,EAAE,kBAAkB,CAAA;CAAE,CAAC,CA2BlF;AAED,iBAAe,0BAA0B,CACvC,OAAO,EAAE,kBAAkB,EAC3B,cAAc,EAAE,oBAAoB,EACpC,WAAW,EAAE,WAAW,EACxB,uBAAuB,EAAE,uBAAuB,GAC/C,OAAO,CAAC,MAAM,CAAC,CA0BjB;AA0CD,iBAAe,qBAAqB,CAClC,OAAO,EAAE,kBAAkB,EAC3B,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC,CAuBlB;AAED,iBAAe,qBAAqB,CAClC,OAAO,EAAE,kBAAkB,EAC3B,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,iBA0BhB;AAED,iBAAS,aAAa,CACpB,OAAO,EAAE,kBAAkB,EAC3B,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,EAAE,WAAW,QAwBvB;AAEH,iBAAS,2BAA2B,CAClC,gBAAgB,EAAE,gBAAgB,EAClC,UAAU,EAAE,MAAM,GACjB,OAAO,CAGT;AAED,iBAAS,0BAA0B,CACjC,gBAAgB,EAAE,gBAAgB,EAClC,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,IAAI,CAYf;AAED,iBAAe,yBAAyB,CACtC,OAAO,EAAE,kBAAkB,EAC3B,WAAW,EAAE,WAAW,EACxB,UAAU,EAAE,MAAM,iBAUnB;AAED,iBAAS,yBAAyB,CAChC,gBAAgB,EAAE,gBAAgB,EAClC,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,SAAS,GACf,OAAO,CA0BT;AASD,iBAAe,yBAAyB,CACtC,kBAAkB,EAAE,kBAAkB,EACtC,aAAa,EAAE,MAAM,EACrB,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC,MAAM,CAAC,CA8CjB;AAED,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,EACrB,aAAa,EACb,2BAA2B,EAC3B,0BAA0B,EAC1B,yBAAyB,EACzB,mCAAmC,EACnC,yBAAyB,EACzB,qBAAqB,EACrB,yBAAyB,EAC1B,CAAA"}
@@ -24,8 +24,8 @@ var _solidLogic = require("solid-logic");
24
24
  var _texts = require("./texts");
25
25
  var _buttonsHelper = require("./buttonsHelper");
26
26
  var _contactsErrors = require("./contactsErrors");
27
- var _contactsPane = _interopRequireDefault(require("contacts-pane"));
28
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
27
+ var _contactsPane = _interopRequireWildcard(require("contacts-pane"));
28
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
29
29
  async function addContactToAddressBook(context, contactsModule, contactData, addressBooksData, container) {
30
30
  const addressBookUriSelectorDialog = (0, _ContactsCard.createAddressBookUriSelectorDialog)(context, contactsModule, contactData, addressBooksData);
31
31
  container.appendChild(addressBookUriSelectorDialog);
@@ -204,8 +204,9 @@ async function addANewAddressBookUriToAddressBooks(context, contactsModule, addr
204
204
  addressBook: contactsAddressBook
205
205
  };
206
206
  }
207
- async function createContactInAddressBook(context, contactsModule, addressBooksData, contactData, selectedAddressBookUris) {
207
+ async function createContactInAddressBook(context, contactsModule, contactData, selectedAddressBookUris) {
208
208
  let contactUri = null;
209
+ const store = context.session.store;
209
210
  const newContact = {
210
211
  name: contactData.name
211
212
  };
@@ -222,7 +223,8 @@ async function createContactInAddressBook(context, contactsModule, addressBooksD
222
223
  return;
223
224
  }
224
225
  await context.session.store.fetcher.load(contactUri);
225
- await addWebIDToContact(context, groupUris, contactUri, contactData.webID);
226
+ const contactNode = new _rdflib.NamedNode(contactUri);
227
+ await (0, _contactsPane.addWebIDToContacts)(contactNode, contactData.webID, _solidUi.ns.vcard('WebID'), store);
226
228
  if (contactData.emails.length || contactData.phoneNumbers.length) {
227
229
  await addContactDetails(context, contactUri, contactData);
228
230
  }
@@ -261,29 +263,6 @@ async function addContactDetails(context, contactUri, contactData) {
261
263
  (0, _contactsErrors.addErrorToErrorDisplay)(context, error);
262
264
  }
263
265
  }
264
- async function addWebIDToContact(context, groupUris, contactUri, webID) {
265
- const store = context.session.store;
266
- const contactNode = new _rdflib.NamedNode(contactUri);
267
- const webIDNode = (0, _rdflib.sym)(webID);
268
- const vcardURLNode = store.bnode();
269
- let groupUriNode = null;
270
- try {
271
- if (groupUris?.length) {
272
- for (const groupUri of groupUris) {
273
- await context.session.store.fetcher.load(groupUri);
274
- groupUriNode = new _rdflib.NamedNode(groupUri);
275
- const groupDoc = groupUriNode.doc();
276
- const deletions = context.session.store.statementsMatching(groupUriNode, _solidUi.ns.vcard('hasMember'), contactNode, groupDoc);
277
- const insertions = [(0, _rdflib.st)(groupUriNode, _solidUi.ns.vcard('hasMember'), webIDNode, groupDoc), (0, _rdflib.st)(webIDNode, _solidUi.ns.owl('sameAs'), contactNode, groupDoc)];
278
- await store.updater.update(deletions, insertions);
279
- }
280
- }
281
- const personInsertions = [(0, _rdflib.st)(contactNode, _solidUi.ns.vcard('url'), vcardURLNode, contactNode.doc()), (0, _rdflib.st)(vcardURLNode, _solidUi.ns.rdf('type'), _solidUi.ns.vcard('WebID'), contactNode.doc()), (0, _rdflib.st)(vcardURLNode, _solidUi.ns.vcard('value'), (0, _rdflib.literal)(webID), contactNode.doc())];
282
- await store.updater.update([], personInsertions);
283
- } catch (error) {
284
- (0, _contactsErrors.addErrorToErrorDisplay)(context, error);
285
- }
286
- }
287
266
  async function addAddressToTypeIndex(context, typeOfIndex, addressBookUri) {
288
267
  const store = context.session.store;
289
268
  const me = _solidLogic.authn.currentUser();
@@ -332,6 +311,7 @@ function refreshButton(context, addressBooksData, contactData) {
332
311
  //logged in and friend exists or friend was just added
333
312
  button.innerHTML = _texts.contactExistsAlreadyButtonText.toUpperCase();
334
313
  button.onclick = null;
314
+ button.setAttribute('disabled', '');
335
315
  } else if (contactExistsByName) {
336
316
  button.innerHTML = _texts.contactExistsAlreadyByNameButtonText.toUpperCase();
337
317
  button.removeAttribute('disabled');
@@ -358,52 +338,16 @@ function checkIfContactExistsByName(addressBooksData, name) {
358
338
  });
359
339
  return contactUri;
360
340
  }
361
- async function addWebIDToExistingContact(context, contactsModule, addressBooksData, webID, contactUri) {
341
+ async function addWebIDToExistingContact(context, contactData, contactUri) {
342
+ const store = context.session.store;
362
343
  try {
363
- const groupUris = await getGroupUrisForContact(contactsModule, addressBooksData, contactUri);
364
- await addWebIDToContact(context, groupUris, contactUri, webID);
344
+ await context.session.store.fetcher.load(contactUri);
345
+ const contactNode = new _rdflib.NamedNode(contactUri);
346
+ await (0, _contactsPane.addWebIDToContacts)(contactNode, contactData.webID, _solidUi.ns.vcard('WebID'), store);
365
347
  } catch (error) {
366
348
  (0, _contactsErrors.addErrorToErrorDisplay)(context, error);
367
349
  }
368
350
  }
369
- async function getGroupUrisForContact(contactsModule, addressBooksData, contactUri) {
370
- let groupUrisForContact = [];
371
- let addressBookForContact = null;
372
- let allGroupUrisForAddressBook = [];
373
- addressBooksData.public.forEach((book, uri) => {
374
- book.contacts.map(contact => {
375
- if (contact.uri === contactUri) {
376
- addressBookForContact = book;
377
- }
378
- });
379
- });
380
- addressBooksData.private.forEach((book, uri) => {
381
- book.contacts.map(contact => {
382
- if (contact.uri === contactUri) {
383
- addressBookForContact = book;
384
- }
385
- });
386
- });
387
- allGroupUrisForAddressBook = addressBookForContact.groups;
388
- const groupPromises = allGroupUrisForAddressBook.map(async group => {
389
- group = await contactsModule.readGroup(group.uri);
390
- return {
391
- groupUri: group.uri,
392
- group
393
- };
394
- });
395
- const groups = await Promise.all(groupPromises);
396
- groups.map(groupInfo => {
397
- groupInfo.group.members.map(contact => {
398
- if (contact.uri === contactUri) {
399
- if (!groupUrisForContact.includes(groupInfo.groupUri)) {
400
- groupUrisForContact.push(groupInfo.groupUri);
401
- }
402
- }
403
- });
404
- });
405
- return groupUrisForContact;
406
- }
407
351
  function addGroupToAddressBookData(addressBooksData, addressBookUri, group) {
408
352
  const publicAddressBook = addressBooksData.public.get(addressBookUri);
409
353
  if (publicAddressBook) {
@@ -429,6 +373,9 @@ function addGroupToAddressBookData(addressBooksData, addressBookUri, group) {
429
373
  }
430
374
  return false;
431
375
  }
376
+ function sanitizeAlphaNumericSpaces(input) {
377
+ return (input || '').replace(/[^a-zA-Z0-9 ]+/g, '').replace(/\s+/g, ' ').trim();
378
+ }
432
379
  async function handleAddressBookCreation(dataBrowserContext, containerName, enteredAddressName) {
433
380
  const me = _solidLogic.authn.currentUser();
434
381
  const newAddressContainer = me?.site()?.value;
@@ -438,8 +385,13 @@ async function handleAddressBookCreation(dataBrowserContext, containerName, ente
438
385
  if (!me || !newAddressContainer) {
439
386
  throw new Error(_texts.errorUnableToDetermineUserWorkspace);
440
387
  }
388
+ const sanitizedAddressName = sanitizeAlphaNumericSpaces(enteredAddressName);
389
+ if (!sanitizedAddressName) {
390
+ throw new Error('Address book name can only contain letters, numbers, and spaces');
391
+ }
392
+ const sanitizedContainerName = sanitizeAlphaNumericSpaces(containerName);
441
393
  const normalizedContainer = newAddressContainer.endsWith('/') ? newAddressContainer : `${newAddressContainer}/`;
442
- const addressBookSlug = (containerName || 'address-book').trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'address-book';
394
+ const addressBookSlug = (sanitizedContainerName || 'address-book').trim().toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]+/g, '-').replace(/^-+|-+$/g, '') || 'address-book';
443
395
  const newBase = `${normalizedContainer}${addressBookSlug}/`;
444
396
  const mintResult = await _contactsPane.default.mintNew(dataBrowserContext, {
445
397
  me,
@@ -447,10 +399,10 @@ async function handleAddressBookCreation(dataBrowserContext, containerName, ente
447
399
  div,
448
400
  newBase,
449
401
  instanceClass: _solidUi.ns.vcard('AddressBook'),
450
- instanceName: enteredAddressName
402
+ instanceName: sanitizedAddressName
451
403
  });
452
404
  addressBookUri = mintResult?.newInstance?.uri || `${newBase}index.ttl#this`;
453
- await updateAddressBookName(dataBrowserContext, addressBookUri, enteredAddressName);
405
+ await updateAddressBookName(dataBrowserContext, addressBookUri, sanitizedAddressName);
454
406
  } catch (error) {
455
407
  (0, _contactsErrors.addErrorToErrorDisplay)(dataBrowserContext, _texts.errorAddressBookCreation + '\n' + error);
456
408
  }