Skip to content

Commit

Permalink
Workaround for bug that prevented editing vCards with commas in… (#1394)
Browse files Browse the repository at this point in the history
Workaround for bug that prevented editing vCards with commas in the address
  • Loading branch information
skjnldsv authored Jan 6, 2020
2 parents df8c466 + 72960f1 commit 438e83e
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 45 deletions.
11 changes: 2 additions & 9 deletions src/mixins/PropertyMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
*/
import debounce from 'debounce'
import Contact from '../models/contact'
import ICAL from 'ical.js'
import { setPropertyAlias } from '../services/updateDesignSet'

export default {
props: {
Expand Down Expand Up @@ -142,14 +142,7 @@ export default {
this.localContact.vCard.addPropertyWithValue(`${group}.x-ablabel`, label)

// force update the main design sets
if (ICAL.design.vcard.property[name]) {
ICAL.design.vcard.property[propGroup]
= ICAL.design.vcard.property[name]
}
if (ICAL.design.vcard3.property[name]) {
ICAL.design.vcard3.property[propGroup]
= ICAL.design.vcard3.property[name]
}
setPropertyAlias(name, propGroup)

this.$emit('update')
},
Expand Down
37 changes: 1 addition & 36 deletions src/models/contact.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import uuid from 'uuid'
import ICAL from 'ical.js'

import store from '../store'
import updateDesignSet from '../services/updateDesignSet'

/**
* Check if the given value is an empty array or an empty string
Expand All @@ -35,40 +36,6 @@ const isEmpty = value => {
return (Array.isArray(value) && value.join('') === '') || (!Array.isArray(value) && value === '')
}

/**
* Parse a jCal and update the global designset
* if any grouped property is found
*
* @param {Array} jCal the contact ICAL.js jCal
* @returns {Boolean}
*/
const updateDesignSet = jCal => {
let result = false
jCal[1].forEach(prop => {
const propGroup = prop[0].split('.')

// if this is a grouped property, update the designSet
if (propGroup.length === 2 && (
ICAL.design.vcard.property[propGroup[1]]
|| ICAL.design.vcard3.property[propGroup[1]]
)) {
// force update the main design sets
if (ICAL.design.vcard.property[propGroup[1]]) {
ICAL.design.vcard.property[prop[0]]
= ICAL.design.vcard.property[propGroup[1]]
result = true
}
if (ICAL.design.vcard3.property[propGroup[1]]) {
ICAL.design.vcard3.property[prop[0]]
= ICAL.design.vcard3.property[propGroup[1]]

result = true
}
}
})
return result
}

export default class Contact {

/**
Expand All @@ -88,8 +55,6 @@ export default class Contact {
throw new Error('Only one contact is allowed in the vcard data')
}

// add grouped properties to the design set
// if any found, refresh the contact jCal
if (updateDesignSet(jCal)) {
jCal = ICAL.parse(vcard)
}
Expand Down
111 changes: 111 additions & 0 deletions src/services/updateDesignSet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/**
* @copyright Copyright (c) 2020 Christian Kraus <hanzi@hanzi.cc>
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
* @author Christian Kraus <hanzi@hanzi.cc>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import ICAL from 'ical.js'

/**
* Fixes nextcloud/contacts#1009 that prevented editing of contacts if
* their address contained a comma. This is actually a bug in ical.js
* but it has not been fixed for some time now.
*
* This can be removed once https://github.com/mozilla-comm/ical.js/issues/386
* has been resolved.
*
* @returns {Boolean} Whether or not the design set has been altered.
*/
const setLabelAsSingleValue = () => {
if (
!ICAL.design.vcard.param.label
|| ICAL.design.vcard.param.label.multiValue !== false
|| !ICAL.design.vcard3.param.label
|| ICAL.design.vcard3.param.label.multiValue !== false
) {
ICAL.design.vcard.param.label = { multiValue: false }
ICAL.design.vcard3.param.label = { multiValue: false }

return true
}

return false
}

/**
* Some clients group properties by naming them something like 'ITEM1.URL'.
* These should be treated the same as their original (i.e. 'URL' in this
* example), so we iterate through the vCard to find these properties and
* add them to the ical.js design set.
*
* @link https://github.com/nextcloud/contacts/issues/42
*
* @param {Array} vCard The ical.js vCard
* @returns {Boolean} Whether or not the design set has been altered.
*/
const addGroupedProperties = vCard => {
let madeChanges = false
vCard[1].forEach(prop => {
const propGroup = prop[0].split('.')

// if this is a grouped property, update the designSet
if (propGroup.length === 2) {
madeChanges = setPropertyAlias(propGroup[1], prop[0])
}
})
return madeChanges
}

/**
* Check whether the ical.js design sets need updating (and if so, do it)
*
* @param {Array} vCard The ical.js vCard
* @returns {boolean} Whether or not the design set has been altered.
*/
export default function(vCard) {
let madeChanges = false

madeChanges |= setLabelAsSingleValue()
madeChanges |= addGroupedProperties(vCard)

return madeChanges
}

/**
* @param {String} original Name of the property whose settings should be copied
* @param {String} alias Name of the new property
* @returns {boolean} Whether or not the design set has been altered.
*/
export function setPropertyAlias(original, alias) {
let madeChanges = false
original = original.toLowerCase()
alias = alias.toLowerCase()

if (ICAL.design.vcard.property[original]) {
ICAL.design.vcard.property[alias] = ICAL.design.vcard.property[original]
madeChanges = true
}

if (ICAL.design.vcard3.property[original]) {
ICAL.design.vcard3.property[alias] = ICAL.design.vcard3.property[original]
madeChanges = true
}

return madeChanges
}

0 comments on commit 438e83e

Please sign in to comment.