GithubHelp home page GithubHelp logo

nextcloud / cdav-library Goto Github PK

View Code? Open in Web Editor NEW
60.0 7.0 15.0 7.39 MB

:date: ๐Ÿ“‡ CalDAV and CardDAV client library for JavaScript

Home Page: https://www.npmjs.com/package/@nextcloud/cdav-library

License: GNU Affero General Public License v3.0

JavaScript 99.92% Makefile 0.08%
javascript caldav carddav nextcloud rfc6352 library js rfc4791 cdav-library

cdav-library's Introduction

cdav-library

NPM Version

๐Ÿ“… ๐Ÿ“‡ CalDAV and CardDAV client library for JavaScript

Build the library

# install dependencies
npm install

# build for dev and watch changes
npm run watch

# build for dev
npm run dev

# build for production with minification
npm run build

Running tests

You can use the provided npm command to run all tests by using:

npm run test

โœŒ๏ธ Code of conduct

The Nextcloud community has core values that are shared between all members during conferences, hackweeks and on all interactions in online platforms including Github and Forums. If you contribute, participate or interact with this community, please respect our shared values. ๐Ÿ˜Œ

โค๏ธ How to create a pull request

This guide will help you get started:

cdav-library's People

Contributors

christophwurst avatar commanderroot avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar georgehrke avatar gretad avatar juliakirschenheuter avatar kesselb avatar nextcloud-bot avatar nextcloud-command avatar npmbuildbot[bot] avatar raimund-schluessler avatar rullzer avatar skjnldsv avatar st3iny avatar tcitworld avatar wilbowma avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

cdav-library's Issues

Allow us to provide custom props on findAllAndFilterBySimpleProperties

After nextcloud/server#14389
I need to be able to request the [NS.NEXTCLOUD, 'has-photo'] prop :)

async findAllAndFilterBySimpleProperties(props) {
const children = [];
props.forEach((prop) => {
children.push({
name: [NS.IETF_CARDDAV, 'prop'],
attributes: [['name', prop]]
});
});
return this.addressbookQuery(null, [{
name: [NS.DAV, 'getetag']
}, {
name: [NS.DAV, 'getcontenttype']
}, {
name: [NS.DAV, 'resourcetype']
}, {
name: [NS.IETF_CARDDAV, 'address-data'],
children: children
}]);
}

@georgehrke

Implement storage

  • Allow users to hand over a storage object (whether it's SessionStorage, LocalStorage or something completely different)
  • Save all objects / properties to Storage

`npm run build-doc` throws an error

OS: ubuntu 20.04 LTS
node: 16.13.0
make: GNU Make 4.2.1

running npm run build-doc throws the following error:

output: /home/mario/cdav-library/docs/class/src/models/addressBookHome.js~AddressBookHome.html
output: /home/mario/cdav-library/docs/class/src/errors/attachError.js~AttachError.html
output: /home/mario/cdav-library/docs/class/src/models/calendar.js~Calendar.html

SyntaxError: Invalid regular expression: /[~](Calendar$/: Unterminated group
    at new RegExp (<anonymous>)
    at ClassDocBuilder._findByName (/home/mario/cdav-library/node_modules/esdoc-publish-html-plugin/out/src/Builder/DocBuilder.js:116:20)
    at ClassDocBuilder._buildDocLinkHTML (/home/mario/cdav-library/node_modules/esdoc-publish-html-plugin/out/src/Builder/DocBuilder.js:782:22)
    at ClassDocBuilder._buildTypeDocLinkHTML (/home/mario/cdav-library/node_modules/esdoc-publish-html-plugin/out/src/Builder/DocBuilder.js:764:19)
    at /home/mario/cdav-library/node_modules/esdoc-publish-html-plugin/out/src/Builder/DocBuilder.js:743:23
    at Array.map (<anonymous>)
    at /home/mario/cdav-library/node_modules/esdoc-publish-html-plugin/out/src/Builder/DocBuilder.js:741:29
    at Array.map (<anonymous>)
    at ClassDocBuilder._buildTypeDocLinkHTML (/home/mario/cdav-library/node_modules/esdoc-publish-html-plugin/out/src/Builder/DocBuilder.js:740:43)
    at ClassDocBuilder._buildSignatureHTML (/home/mario/cdav-library/node_modules/esdoc-publish-html-plugin/out/src/Builder/DocBuilder.js:860:36)

Where is the API? How do I use it?

Hi,

I'm hoping there can be an API or something to allow people to use this library.

In particular I would like a complete example of how to authenticate and get calendars and events,
as well as how to set them.

I found a partial example in #36

await client.connect({enableCalDAV: true});
const calendars = await client.calendarHomes[0].findAllCalDAVCollections()
const events = await calendars[0].findAllVObjects()
console.log(events[0].data);

but it seems incomplete, like where do I put the username and password or apiKey?
Also how would I set new events?

Examples of how to use the cardDav would be great also.

Thanks

IE11 compatibility

  • Implement babel polyfill
  • Make sure this lib is ie11 compatible (currently breaking the contacts app on ie)

Installing this via npm broken by one of the newer commits

I'm installing this lib via npm like so:

npm i git+https://github.com/nextcloud/cdav-library.git

Which won't properly install anything, just an empty directory apart from the package.json.

Fixed by executing:

npm i git+https://github.com/nextcloud/cdav-library.git#d8cdc23df38b10641f52ec97fd2daa86080cfe1d

Cannot read property 'length' of undefined

dist.js:formatted:1 TypeError: Cannot read property 'length' of undefined
    at dist.js:formatted:1
    at Array.forEach (<anonymous>)
    at e.value (dist.js:formatted:1)
    at e.<anonymous> (dist.js:formatted:1)
    at c (dist.js:formatted:1)
    at Generator._invoke (dist.js:formatted:1)
    at Generator.forEach.t.<computed> [as next] (dist.js:formatted:1)
    at Ot (dist.js:formatted:1)
    at a (dist.js:formatted:1)

if (props['{DAV:}resourcetype'].length === 0) {

Got this when uploading some vcf to a customer instance.
Not sure why, only happened 3 times over a 200+ list of contacts ๐Ÿคท

Versioning and publishing

I read in #325 that the lib was not put on the npm registry deliberately. However, I now also see that when it's used in apps you don't have any versioning (except from commits) and therefore it's a bit hard to keep book about what version is used in which app/release, especially when it comes to backports.

Therefore I think publishing still makes sense. The app can be namespaced with @nextcloud/ like the other packages and we can make it clear that this package is for internals of Nextcloud and no general purpose webdav lib.

@juliushaertl @skjnldsv @tcitworld objections?

Make a proper module of it?

Just writing a quick note to ask if there's some kind of reason this has not been published to npm registry (or maybe it is published but I have missed it)? Would be good to rely on semver and install easily into projects.

Integration Tests

I'd like to have integration tests that test this library against the real Nextcloud CalDAV and CardDAV server.

Any suggestions for an integration test framework?

npm package is outdated

Steps to reproduce

1.search for nextcloud caldav on https://www.npmjs.com
2. find the npm package

Expected behavior

expected version 1.2.0 released in december 2022

Actual behavior

found version 1.1.0 published "a year ago"

Library version

No response

Additional info

No response

Implement Sharing

  • complete implementation for davCollectionShareable
  • implement principalPropertySearch to search for users and groups

Requirements for CardDAV

Hey @Henni @skjnldsv

One thing you can do before we get started in a couple of weeks would be documenting requirements for the CardDAV library.

Stuff like:

  • queries with limit/offset (lazy loading)
  • load contacts by groups
  • "group statistics" (you probably need some way to get a list of all groups / the number of contacts per group without loading all contacts first)
  • etc.
  • filter out unwanted properties of vcards/ical

Do you need some kind of search API for filter all contacts by their properties?

fix coverage reports

Coverage reports are not generated correctly.

Fixing

preprocessors: { 'js/**/*.js': ['coverage'] },
to say preprocessors: { 'src/**/*.js': ['coverage'] }, instead of preprocessors: { 'js/**/*.js': ['coverage'] }, breaks all unit tests and throws many "unexpected token: numeric literal".

Most likely istanbul / karma-coverage don't support ES6 modules fully natively yet. (without webpack).

Find VTODO by status

For the Tasks app I would need a function findVTODObyStatus(completed = false, related = null) that allows to

  • find all not completed tasks in a calendar
  • find all completed tasks in a calendar
  • find all completed tasks related to an other task

The specific calendarQueries would look like this:

// find all not completed tasks in a calendar
calendarQuery(
	[{
		name: [NS.IETF_CALDAV, 'comp-filter'],
		attributes: [
			['name', 'VCALENDAR']
		],
		children: [{
			name: [NS.IETF_CALDAV, 'comp-filter'],
			attributes: [
				['name', 'VTODO']
			],
			children: [{
				name: [NS.IETF_CALDAV, 'prop-filter'],
				attributes: [
					['name', 'completed']
				],
				children: [{
					name: [NS.IETF_CALDAV, 'is-not-defined']
				}]
			}]
		}]
	}]
)

// find all completed tasks in a calendar
calendarQuery(
	[{
		name: [NS.IETF_CALDAV, 'comp-filter'],
		attributes: [
			['name', 'VCALENDAR']
		],
		children: [{
			name: [NS.IETF_CALDAV, 'comp-filter'],
			attributes: [
				['name', 'VTODO']
			],
			children: [{
				name: [NS.IETF_CALDAV, 'prop-filter'],
				attributes: [
					['name', 'completed']
				]
			}]
		}]
	}]
)

// find all completed tasks related to an other task
var parentUID = 'exampleUID'
calendarQuery(
	[{
		name: [NS.IETF_CALDAV, 'comp-filter'],
		attributes: [
			['name', 'VCALENDAR']
		],
		children: [{
			name: [NS.IETF_CALDAV, 'comp-filter'],
			attributes: [
				['name', 'VTODO']
			],
			children: [
				{
					name: [NS.IETF_CALDAV, 'prop-filter'],
					attributes: [
						['name', 'completed']
					]
				},
				{
					name: [NS.IETF_CALDAV, 'prop-filter'],
					attributes: [
						['name', 'related-to']
					],
					children: [{
						name: [NS.IETF_CALDAV, 'text-match'],
						value: parentUID
					}]
				}
			]
		}]
	}]
)

Since this is pretty specific for the Tasks app, I wonder whether this should be included in the cdav-library or better only in the Tasks app.

I tend to have that in the Tasks app, but I don't know how to access NS.IETF_CALDAV variable when sending a calendar query.

Conflict handling is broken

Hey @georgehrke
When I added the etag writing thing, I made sure that in case of conflict, the contact was set to being partial (since data was missing and/or changed)

if (res.status === 412) {
// wrong etag do not update the new etag
this._isPartial = true;
} else {

But this is not the case anymore and is therefore breaking the contacts behavior since forcing a fullfetch will return undefined instead of updating the vcard data.

async update() {
// 1. Do not update filtered objects, because we would be loosing data on the server
// 2. No need to update if object was never modified
// 3. Do not update if called directly on DavObject, because there is no data prop
if (this.isPartial() || !this.isDirty() || !this.data) {
return;
}
return this._request.put(this.url, { 'If-Match': this.etag }, this.data).then((res) => {
this._isDirty = false;
// Don't overwrite content-type, it's set to text/html in the response ...
this._props['{DAV:}getetag'] = res.xhr.getResponseHeader('etag');
});
}

What shall we do here?
Shall I manually set the contact to partial?
I feel like this should be built-in ๐Ÿค”

General-purpose WebDAV library

We should turn this library into a general-purpose webdav library.
A plugin system should allow for extensibility.

CalDAV and CardDAV should be moved out of the core lib and into their own plugins.
(Their API should remain the same though)

Additional plugins that are needed for the Files App:

  • Files
  • FileComments
  • FileVersioning
  • (Trashbin?)
  • SystemTags

It should be enough if the core lib provides:

  • Parser
  • Request
  • DavObject
  • DavCollection
  • XMLBuilder

(The entire principal stuff should be part of the CalDAV / CardDAV plugin)

Wrong Content-Type request header in PUT requests

Steps to reproduce

Case 1

  1. Open Tasks list in browser
  2. Check existing task

Case 2

  1. Open Tasks list in browser
  2. Open details of existing task
  3. Rename task
  4. Apply

Expected behaviour

Created PUT request header should have Content-Type text/calendar; charset=utf-8.

Actual behaviour

Created PUT request header has Content-Type application/xml; charset=utf-8. The request data is an iCalendar string, which is not XML.

Why is that a problem?

ModSecurity Web Application Firewall (as used in NextCloudPi) fails trying to parse incoming XML data.

Client configuration

Browser: Firefox 91.0
Operating system: Linux Mint 20

Make requests cancellable

This would be especially useful for calendar.

When navigating thru multiple months very fast, it doesn't cancel requests at the moment but loads all the months you visited.

The "Automatically Generate A Birthday Calendar" feature doesn't work.

Steps to reproduce

  1. Check the box for "Automatically generate a birthday calendar"
  2. Wait a long time, like hours.
  3. Look for Birthday's on a calendar, or a new calendar called Birthday's, but don't find one.

Expected behavior

A new calendar for a user should appear with birthdays that are stored in the contact's list.

Actual behavior

Nothing

Server configuration detail

Operating system: Linux 4.4.0-127-generic #153-Ubuntu SMP Sat May 19 10:58:46 UTC 2018 x86_64

Webserver: Apache/2.4.18 (cgi-fcgi)

Database: mysql 10.0.34

PHP version: 7.0.30-0ubuntu0.16.04.1
Modules loaded: Core, date, libxml, openssl, pcre, zlib, filter, hash, pcntl, Reflection, SPL, session, standard, cgi-fcgi, mysqlnd, PDO, xml, apcu, bz2, calendar, ctype, curl, dom, mbstring, fileinfo, ftp, gd, gettext, gmp, iconv, igbinary, imagick, imap, intl, json, ldap, exif, mcrypt, mysqli, pdo_mysql, pdo_pgsql, pdo_sqlite, pgsql, Phar, posix, pspell, readline, redis, shmop, SimpleXML, soap, sockets, sqlite3, sysvmsg, sysvsem, sysvshm, tokenizer, wddx, xmlreader, xmlrpc, xmlwriter, xsl, zip, Zend OPcache

Nextcloud version: 13.0.2 - 13.0.2.1

Updated from an older Nextcloud/ownCloud or fresh install: Upgraded

Where did you install Nextcloud from: NextCloud website for Ubuntu instructions

Signing status

Array

List of activated apps
Enabled:
 - activity: 2.6.1
 - admin_notifications: 1.0.1
 - announcementcenter: 3.2.1
 - apporder: 0.4.1
 - audioplayer: 2.3.0
 - bookmarks: 0.11.0
 - bruteforcesettings: 1.0.3
 - calendar: 1.6.1
 - checksum: 0.4.0
 - circles: 0.13.6
 - comments: 1.3.0
 - contacts: 2.1.5
 - data_request: 1.0.0
 - dav: 1.4.6
 - deck: 0.3.1
 - drawio: 0.8.9
 - drop_account: 0.0.11
 - external: 3.0.3
 - federatedfilesharing: 1.3.1
 - federation: 1.3.0
 - files: 1.8.0
 - files_antivirus: 1.2.0
 - files_downloadactivity: 1.2.0
 - files_pdfviewer: 1.2.1
 - files_retention: 1.2.0
 - files_sharing: 1.5.0
 - files_texteditor: 2.5.1
 - files_trashbin: 1.3.0
 - files_versions: 1.6.0
 - files_videoplayer: 1.2.0
 - firstrunwizard: 2.2.1
 - flowupload: 0.0.7
 - gallery: 18.0.0
 - gpxedit: 0.0.8
 - gpxmotion: 0.0.6
 - gpxpod: 2.2.2
 - groupfolders: 1.2.0
 - issuetemplate: 0.3.0
 - keeporsweep: 0.1.4
 - logreader: 2.0.0
 - lookup_server_connector: 1.1.0
 - metadata: 0.6.0
 - news: 12.0.1
 - nextcloud_announcements: 1.2.0
 - notes: 2.3.2
 - notifications: 2.1.2
 - oauth2: 1.1.0
 - ocsms: 1.12.7
 - password_policy: 1.3.0
 - phonetrack: 0.2.7
 - polls: 0.8.1
 - provisioning_api: 1.3.0
 - quota_warning: 1.2.0
 - radio: 0.6.1
 - rainloop: 5.1.0
 - ransomware_protection: 1.1.0
 - richdocuments: 2.0.8
 - serverinfo: 1.3.0
 - sharebymail: 1.3.0
 - socialsharing_diaspora: 1.0.2
 - socialsharing_email: 1.0.3
 - socialsharing_facebook: 1.0.2
 - socialsharing_googleplus: 1.0.2
 - socialsharing_twitter: 1.0.2
 - spreed: 3.2.1
 - survey_client: 1.1.0
 - systemtags: 1.3.0
 - tasks: 0.9.6
 - telephoneprovider: 1.0.1
 - theming: 1.4.5
 - twofactor_backupcodes: 1.2.3
 - updatenotification: 1.3.0
 - weather: 1.5.1
 - workflowengine: 1.3.0
Disabled:
 - admin_audit
 - encryption
 - files_external
 - user_external
 - user_ldap

Configuration (config/config.php)
{
    "instanceid": "***REMOVED SENSITIVE VALUE***",
    "passwordsalt": "***REMOVED SENSITIVE VALUE***",
    "secret": "***REMOVED SENSITIVE VALUE***",
    "trusted_domains": [
        "cloud.myexample.com"
    ],
    "datadirectory": "***REMOVED SENSITIVE VALUE***",
    "dbtype": "mysql",
    "version": "13.0.2.1",
    "dbname": "***REMOVED SENSITIVE VALUE***",
    "dbhost": "***REMOVED SENSITIVE VALUE***",
    "dbport": "",
    "dbtableprefix": "oc_",
    "mysql.utf8mb4": true,
    "dbuser": "***REMOVED SENSITIVE VALUE***",
    "dbpassword": "***REMOVED SENSITIVE VALUE***",
    "installed": true,
    "mail_from_address": "***REMOVED SENSITIVE VALUE***",
    "mail_smtpmode": "smtp",
    "mail_smtpauthtype": "LOGIN",
    "mail_domain": "***REMOVED SENSITIVE VALUE***",
    "mail_smtphost": "***REMOVED SENSITIVE VALUE***",
    "mail_smtpport": "587",
    "mail_smtpauth": 1,
    "mail_smtpname": "***REMOVED SENSITIVE VALUE***",
    "mail_smtppassword": "***REMOVED SENSITIVE VALUE***",
    "maintenance": false,
    "memcache.local": "\\OC\\Memcache\\APCu",
    "theme": "",
    "updater.secret": "***REMOVED SENSITIVE VALUE***",
    "loglevel": 0,
    "default_language": "en",
    "enable_previews": true,
    "preview_max_x": 2048,
    "preview_max_y": 2048,
    "preview_max_scale_factor": 10,
    "preview_max_filesize_image": 50,
    "preview_libreoffice_path": "\/usr\/bin\/libreoffice",
    "preview_office_cl_parameters": " --headless --nologo --nofirststartwizard --invisible --norestore --convert-to pdf --outdir ",
    "enabledPreviewProviders": [
        "OC\\Preview\\PNG",
        "OC\\Preview\\JPEG",
        "OC\\Preview\\GIF",
        "OC\\Preview\\BMP",
        "OC\\Preview\\XBitmap",
        "OC\\Preview\\SVG",
        "OC\\Preview\\TIFF",
        "OC\\Preview\\MP3",
        "OC\\Preview\\TXT",
        "OC\\Preview\\Font",
        "OC\\Preview\\MarkDown",
        "OC\\Preview\\Movie",
        "OC\\Preview\\MSOffice2003",
        "OC\\Preview\\MSOffice2007",
        "OC\\Preview\\MSOfficeDoc",
        "OC\\Preview\\OpenDocument",
        "OC\\Preview\\PDF",
        "OC\\Preview\\Postscript",
        "OC\\Preview\\StarOffice"
    ],
    "tempdirectory": "\/home\/webserverowner\/domains\/cloud.myexample.com\/tmp\/nextcloudtemp",
    "overwrite.cli.url": "https:\/\/cloud.myexample.com"
}

Client configuration

Browser: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0

Operating system: Ubuntu 18.04 workstation

Logs

Nextcloud log

screenshot_from_2018-06-01_22-26-05

nextcloud.log

Need Help in addressbookQuery

@georgehrke
please help with filter query.
I want to get only contacts whose TITLE contains ssss.
I used following query

addressbookQuery([
  {
    name: [NS.IETF_CALDAV, 'prop-filter'],
    attributes: [['name', 'TITLE']],
    children: [
      {
        name: [NS.IETF_CALDAV, 'text-match'],
        attributes: [
          ['collation', 'i;unicode-casemap'],
          ['match-type', 'contains'],
        ],
        value: "ssss",
      },
    ],
  },
] , null, null,  'allof') 

REPORT Request shows

<x3:addressbook-query xmlns:x3="urn:ietf:params:xml:ns:carddav">
    <x0:prop xmlns:x0="DAV:">
        <x0:getcontenttype/>
        <x0:getetag/>
        <x0:resourcetype/>
        <x0:displayname/>
        <x0:owner/>
        <x0:resourcetype/>
        <x0:sync-token/>
        <x0:current-user-privilege-set/>
        <x0:getcontenttype/>
        <x0:getetag/>
        <x0:resourcetype/>
        <x3:address-data/>
    </x0:prop>
    <x3:filter test="allof">
        <x1:prop-filter xmlns:x1="urn:ietf:params:xml:ns:caldav" name="TITLE">
            <x1:text-match collation="i;unicode-casemap" match-type="contains">ssss</x1:text-match>
        </x1:prop-filter>
    </x3:filter>
</x3:addressbook-query>

But unfortunately i get contacts with TITLE other than ssss.

Here is the multi repsponse:

<?xml version="1.0"?>
<d:multistatus xmlns:d="DAV:" 
    xmlns:s="http://sabredav.org/ns" 
    xmlns:card="urn:ietf:params:xml:ns:carddav" 
    xmlns:oc="http://owncloud.org/ns" 
    xmlns:nc="http://nextcloud.org/ns">
    <d:response>
        <d:href>/remote.php/dav/addressbooks/users/admin/adrbook/F9562A8F-C826-4754-BAEA-A062704CBB54.vcf</d:href>
        <d:propstat>
            <d:prop>
                <d:getcontenttype>text/vcard; charset=utf-8</d:getcontenttype>
                <d:getetag>&quot;d946b9fec07d6fabc094852f1e424c39&quot;</d:getetag>
                <d:resourcetype/>
                <d:owner>
                    <d:href>/remote.php/dav/principals/users/admin/</d:href>
                </d:owner>
                <d:current-user-privilege-set>
                    <d:privilege>
                        <d:read/>
                    </d:privilege>
                    <d:privilege>
                        <d:read-acl/>
                    </d:privilege>
                    <d:privilege>
                        <d:read-current-user-privilege-set/>
                    </d:privilege>
                </d:current-user-privilege-set>
                <card:address-data>
BEGIN:VCARD&#13;
VERSION:3.0&#13;
PRODID:-//Sabre//Sabre VObject 4.1.6//EN&#13; 
URI:1ede8db0-a457-4b60-a454-507c28bf36d6.vcf&#13;
UID:1ede8db0-a457-4b60-a454-507c28bf36d6&#13; 
REV;VALUE=DATE-AND-OR-TIME:20191001T101225Z&#13; 
FN:ssss&#13; 
ADR;TYPE=HOME:;;;;;;&#13; 
EMAIL;TYPE=HOME:[email protected]&#13; 
TEL;TYPE=&quot;HOME,VOICE&quot;:1`131243&#13;
NICKNAME:ssss&#13;
N:1;user;dd;Mr;ssss&#13;
ORG:ssss&#13;
TITLE:ssssssss&#13;
END:VCARD&#13;
                </card:address-data>
            </d:prop>
            <d:status>HTTP/1.1 200 OK</d:status>
        </d:propstat>
        <d:propstat>
            <d:prop>
                <d:displayname/>
                <d:sync-token/>
            </d:prop>
            <d:status>HTTP/1.1 404 Not Found</d:status>
        </d:propstat>
    </d:response>
    <d:response>
        <d:href>/remote.php/dav/addressbooks/users/admin/adrbook/595ccfb9-9a42-4444-b52e-33e6df311483.vcf</d:href>
        <d:propstat>
            <d:prop>
                <d:getcontenttype>text/vcard; charset=utf-8</d:getcontenttype>
                <d:getetag>&quot;f96d24f6422a42781230068b9a376ce1&quot;</d:getetag>
                <d:resourcetype/>
                <d:owner>
                    <d:href>/remote.php/dav/principals/users/admin/</d:href>
                </d:owner>
                <d:current-user-privilege-set>
                    <d:privilege>
                        <d:read/>
                    </d:privilege>
                    <d:privilege>
                        <d:read-acl/>
                    </d:privilege>
                    <d:privilege>
                        <d:read-current-user-privilege-set/>
                    </d:privilege>
                </d:current-user-privilege-set>
                <card:address-data>
BEGIN:VCARD&#13;
VERSION:3.0&#13;
PRODID:-//Sabre//Sabre VObject 4.1.6//EN&#13;
URI:595ccfb9-9a42-4444-b52e-33e6df311483.vcf&#13;
UID:595ccfb9-9a42-4444-b52e-33e6df311483&#13;
EMAIL:[email protected]&#13;
FN:dfg dfh&#13;
N:dfh;dfg;dfh;;&#13;
X-ABUID:000001&#13;
ADDRESSBOOK-KEY:6&#13;
ADR:;;;;;;&#13;
TITLE:somwthing new&#13;
END:VCARD&#13;
                </card:address-data>
            </d:prop>
            <d:status>HTTP/1.1 200 OK</d:status>
        </d:propstat>
        <d:propstat>
            <d:prop>
                <d:displayname/>
                <d:sync-token/>
            </d:prop>
            <d:status>HTTP/1.1 404 Not Found</d:status>
        </d:propstat>
    </d:response>
</d:multistatus>

Did i miss anything?

propfind assumes DAV header always exists and causes null exception when missing

Steps to reproduce

Trying to use caldav to sync Super-Productivity[1] app with Mailcow/SOGo[2] server calendar.

  1. Spin up dockerized mailcow.
    a. Create mail account.
    b. Login to mail account.
    c. Open calendar.
    d. Click on "3-dot" icon next to calendar name, select "Links to this Calendar"
    e. Copy authorized caldav url.
  2. Clone Super-Productivity repo: git clone [email protected]:johannesjo/super-productivity.git
  3. Set up dev environment: cd super-productivity; npm i @angular/cli; npm i
  4. Run dev app: npm run ng serve, then in another terminal npm start
  5. In Super-Productivity, find Inbox in Projects drawer (left side), select "Settings" from "3-dot" icon for Inbox.
  6. Expand CalDav Issue Integration.
    a. Enable caldav.
    b. Enter caldav url from step (1.e). E.g. https://mail.example.com/SOGo/dav
    c. Enter caldav path from step (1.e). E.g. Calendar/personal
    d. Enter username
    e. Enter password
    f. Enable four checkbox/toggles below: Show uncompleted..., Auto poll..., Auto add..., and Auto complete....
  7. Open dev tools with Ctrl-Shift-I.
  8. Select Console tab and observe "Caldav: Error: CALDAV NETWORK ERROR: TypeError: Cannot read properties of null (reading 'split')"

[1]: https://github.com/johannesjo/super-productivity
[2]: https://github.com/mailcow/mailcow-dockerized

Expected behavior

Expected no type error.

If library needs DAV header, then it should first make an OPTIONS request which must deliver a DAV header to comply with spec, then perform a subsequent PROPFIND request for other fields.

Actual behavior

"Caldav: Error: CALDAV NETWORK ERROR: TypeError: Cannot read properties of null (reading 'split')" crashes caldav sync in SuperProductivity.

Library version

1.1.0

Additional info

Suspect code

At index.js:155, request.propfind initiates the a PROPFIND request.

At index.js:158, _extractAdvertisedDavFeatures is called.

At index.js:541-542, the DAV: header is retrieved and sliced without a null check.

SOGo behavior

If I use curl to execute PROPFIND, SOGo never provides a DAV header.
If I use curl to execute OPTIONS, SOGo provides a DAV header.

E.g.

(curl --user "name:pass" -s -X PROPFIND -H "Content-Type: application/xml" -D /dev/stderr https://mail.example.com/SOGo/dav/name%40example.com | xmllint -format -) 2>&1 | bat
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
       โ”‚ STDIN
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
   1   โ”‚ HTTP/2 207
   2   โ”‚ server: nginx
   3   โ”‚ date: Sat, 02 Mar 2024 03:37:17 GMT
   4   โ”‚ content-type: text/xml; charset=utf-8
   5   โ”‚ content-length: 3883
   6   โ”‚ x-dav-error: 200 No error
   7   โ”‚ ms-author-via: DAV
   8   โ”‚ pragma: no-cache
   9   โ”‚ cache-control: no-cache
  10   โ”‚ x-frame-options: SAMEORIGIN
  11   โ”‚
  12   โ”‚ <?xml version="1.0" encoding="utf-8"?>
  13   โ”‚ <D:multistatus xmlns:ap="http://apache.org/dav/props/" xmlns:D="DAV:">
  14   โ”‚   <D:response>
  15   โ”‚     <D:href>/SOGo/dav/name%40example.com/freebusy.ifb</D:href>
  16   โ”‚     <D:propstat>
  17   โ”‚       <D:status>HTTP/1.1 200 OK</D:status>
  18   โ”‚       <D:prop>
  19   โ”‚         <D:getlastmodified>Fri, 01 Mar 2024 22:38:53 -0500</D:getlastmodified>
  20   โ”‚         <D:resourcetype/>
  21   โ”‚         <D:getcontenttype>text/calendar</D:getcontenttype>
  22   โ”‚         <D:displayname>freebusy.ifb</D:displayname>
  23   โ”‚         <D:href>/SOGo/dav/name%40example.com/freebusy.ifb</D:href>
  24   โ”‚         <ap:executable>0</ap:executable>
  25   โ”‚       </D:prop>
  26   โ”‚     </D:propstat>
  27   โ”‚   </D:response>
  ...  โ”‚
 158   โ”‚ </D:multistatus>
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€


(curl --user "name:pass" -s -X OPTIONS -H "Content-Type: application/xml" -D /dev/stderr https://mail.example.com/SOGo/dav/name%40example.com) 2>&1 | bat
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
       โ”‚ STDIN
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
   1   โ”‚ HTTP/2 200
   2   โ”‚ server: nginx
   3   โ”‚ date: Sat, 02 Mar 2024 03:40:04 GMT
   4   โ”‚ content-type: text/plain; charset=utf-8
   5   โ”‚ content-length: 0
   6   โ”‚ allow: GET, HEAD, POST, OPTIONS, MKCOL, MKCALENDAR, DELETE, PUT, LOCK, UNLOCK, COPY, MOVE, REPORT, PROPFIND, SEARCH
   7   โ”‚ dav: 1, 2, access-control, addressbook, calendar-access, calendar-schedule, calendar-auto-schedule, calendar-proxy, calendar-query-extended, extended-mkcol, calendarserver-principal-property-search
   8   โ”‚ strict-transport-security: max-age=15768000;
   9   โ”‚ x-content-type-options: nosniff
  10   โ”‚ x-xss-protection: 1; mode=block
  11   โ”‚ x-robots-tag: none
  12   โ”‚ x-download-options: noopen
  13   โ”‚ x-frame-options: SAMEORIGIN
  14   โ”‚ x-permitted-cross-domain-policies: none
  15   โ”‚ referrer-policy: strict-origin
  16   โ”‚
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

WebDAV Spec

According to the spec, PROPFIND uses DAV XML elements, but doesn't explicitly state a requirement/expectation for a DAV header [1].

Further along, the OPTIONS method is required to return the DAV header [2].

All DAV-compliant resources MUST return the DAV header with compliance-class "1" on all OPTIONS responses

Section F.3 makes the claim that DAV header can be used with requests [3]. I don't know whether "requests" in this context refers to other WebDAV methods.

The DAV header now allows non-IETF extensions through URIs in addition to compliance class tokens. It also can now be used in requests, although this specification does not define any associated semantics for the compliance classes defined in here (see Section 10.1).

[1]: http://www.webdav.org/specs/rfc4918.html#METHOD_PROPFIND
[2]: http://www.webdav.org/specs/rfc4918.html#HEADER_DAV
[3]: http://www.webdav.org/specs/rfc4918.html#n-other-changes

documentation: how to run

Hi All,
do you have any documentation how to run or how to integrate with already existing node application?
I thought that I will run

# set up and build for production
make

# install dependencies
make dev-setup

# build for dev and watch changes
make watch-js

then open the web browser on localhost:3000 and will see some client but nothing happens.
Thank you for advice
Jan

How to create Event?

@georgehrke
I came across createVObject api. but I'm not sure what to send as string parameter.
I get 415 Unsupported Media Type
One example would be better.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.