From 1f8e4507632dd43309366b1df5ecbefa5a4a8406 Mon Sep 17 00:00:00 2001 From: Crash-- Date: Tue, 31 Jan 2023 08:08:14 +0100 Subject: [PATCH] feat: Add sourceAccount & sourceAccountIdentifier to createFile Konnectors need to pass the sourceAccount & sourceAccountIdentifier to POST /files/ in order to let the stack set the right cozyMetadata. --- docs/api/cozy-stack-client.md | 16 ++++++++ packages/cozy-client/src/CozyClient.spec.js | 2 +- .../cozy-stack-client/src/FileCollection.js | 12 +++++- .../src/FileCollection.spec.js | 41 +++++++++++++++++-- 4 files changed, 65 insertions(+), 6 deletions(-) diff --git a/docs/api/cozy-stack-client.md b/docs/api/cozy-stack-client.md index 9c1be53bd..8e02b226d 100644 --- a/docs/api/cozy-stack-client.md +++ b/docs/api/cozy-stack-client.md @@ -164,6 +164,9 @@ Deleted and design docs are filtered by default, thus documents are retrieved in
IOCozyFolder : object

Folder

+
SpecificFileAttributesForKonnector : object
+

Specific file attributes for creation for konnector

+
CouchDBViewCursor : Array.<string> | string

Cursor used for Mango queries pagination

@@ -2246,6 +2249,19 @@ You should use fetchChangesRaw to have low level control on _changes parameters. Folder **Kind**: global typedef + + +## SpecificFileAttributesForKonnector : object +Specific file attributes for creation for konnector + +**Kind**: global typedef +**Properties** + +| Name | Type | Description | +| --- | --- | --- | +| sourceAccount | string | the id of the source account used by a konnector | +| sourceAccountIdentifier | string | the unique identifier of the account targeted by the connector | + ## CouchDBViewCursor : Array.<string> \| string diff --git a/packages/cozy-client/src/CozyClient.spec.js b/packages/cozy-client/src/CozyClient.spec.js index 68d7d7fe8..641326742 100644 --- a/packages/cozy-client/src/CozyClient.spec.js +++ b/packages/cozy-client/src/CozyClient.spec.js @@ -1905,7 +1905,7 @@ describe('file creation', () => { expect(doc._id).toEqual('1337') expect(client.stackClient.fetchJSON).toHaveBeenCalledWith( 'POST', - '/files/folder-id?Name=toto.pdf&Type=file&Executable=false&Encrypted=false&MetadataID=&Size=12', + '/files/folder-id?Name=toto.pdf&Type=file&Executable=false&Encrypted=false&MetadataID=&Size=12&SourceAccount=&SourceAccountIdentifier=', 'file-content', { headers: { 'Content-Type': 'text/plain', 'Content-Length': '12' }, diff --git a/packages/cozy-stack-client/src/FileCollection.js b/packages/cozy-stack-client/src/FileCollection.js index 731947be7..37444d16e 100644 --- a/packages/cozy-stack-client/src/FileCollection.js +++ b/packages/cozy-stack-client/src/FileCollection.js @@ -15,6 +15,11 @@ import logger from './logger' /** * @typedef {object} IOCozyFolder Folder */ +/** + * @typedef {object} SpecificFileAttributesForKonnector Specific file attributes for creation for konnector + * @property {string} sourceAccount the id of the source account used by a konnector + * @property {string} sourceAccountIdentifier the unique identifier of the account targeted by the connector + */ /** * Cursor used for Mango queries pagination * @@ -520,9 +525,10 @@ class FileCollection extends DocumentCollection { /** * Creates a file * + * * @private * @param {File|Blob|Stream|string|ArrayBuffer} data file to be uploaded - * @param {FileAttributes} params Additional parameters + * @param {FileAttributes & SpecificFileAttributesForKonnector} params Additional parameters * @param {object} params.options Options to pass to doUpload method (additional headers) * @throws {Error} - explaining reason why creation failed */ @@ -534,6 +540,8 @@ class FileCollection extends DocumentCollection { executable = false, encrypted = false, metadata, + sourceAccount = '', + sourceAccountIdentifier = '', ...options } = {} ) { @@ -554,7 +562,7 @@ class FileCollection extends DocumentCollection { if (options.contentLength) { size = String(options.contentLength) } - const path = uri`/files/${dirId}?Name=${name}&Type=file&Executable=${executable}&Encrypted=${encrypted}&MetadataID=${metadataId}&Size=${size}` + const path = uri`/files/${dirId}?Name=${name}&Type=file&Executable=${executable}&Encrypted=${encrypted}&MetadataID=${metadataId}&Size=${size}&SourceAccount=${sourceAccount}&SourceAccountIdentifier=${sourceAccountIdentifier}` return this.doUpload(data, path, options) } diff --git a/packages/cozy-stack-client/src/FileCollection.spec.js b/packages/cozy-stack-client/src/FileCollection.spec.js index be1dc1f09..34db88ed7 100644 --- a/packages/cozy-stack-client/src/FileCollection.spec.js +++ b/packages/cozy-stack-client/src/FileCollection.spec.js @@ -1137,7 +1137,7 @@ describe('FileCollection', () => { it('should create a file without metadata', async () => { const params = { dirId } const result = await collection.createFile(data, params) - const expectedPath = `/files/${dirId}?Name=mydoc.epub&Type=file&Executable=false&Encrypted=false&MetadataID=&Size=&UpdatedAt=${new Date( + const expectedPath = `/files/${dirId}?Name=mydoc.epub&Type=file&Executable=false&Encrypted=false&MetadataID=&Size=&SourceAccount=&SourceAccountIdentifier=&UpdatedAt=${new Date( data.lastModified ).toISOString()}&CreatedAt=${new Date(data.lastModified).toISOString()}` const expectedOptions = { @@ -1173,7 +1173,7 @@ describe('FileCollection', () => { metadata: { type: 'bill' } } const result = await collection.createFile(data, params) - const expectedPath = `/files/${dirId}?Name=mydoc.epub&Type=file&Executable=false&Encrypted=false&MetadataID=${metadataId}&Size=&UpdatedAt=${new Date( + const expectedPath = `/files/${dirId}?Name=mydoc.epub&Type=file&Executable=false&Encrypted=false&MetadataID=${metadataId}&Size=&SourceAccount=&SourceAccountIdentifier=&UpdatedAt=${new Date( data.lastModified ).toISOString()}&CreatedAt=${new Date(data.lastModified).toISOString()}` const expectedOptions = { @@ -1202,7 +1202,42 @@ describe('FileCollection', () => { const result = await collection.createFile(data, params) const expectedPath = `/files/${dirId}?Name=mydoc.epub&Type=file&Executable=false&Encrypted=false&MetadataID=&Size=${String( contentLength - )}&UpdatedAt=${new Date( + )}&SourceAccount=&SourceAccountIdentifier=&UpdatedAt=${new Date( + data.lastModified + ).toISOString()}&CreatedAt=${new Date(data.lastModified).toISOString()}` + const expectedOptions = { + headers: { + 'Content-Type': 'application/epub+zip', + 'Content-Length': String(contentLength) + } + } + expect(client.fetchJSON).toHaveBeenCalledWith( + 'POST', + expectedPath, + data, + expectedOptions + ) + expect(result).toEqual({ + data: { + id: id, + _id: id, + _type: 'io.cozy.files', + dir_id: dirId + } + }) + }) + + it('should send the file konnectors params via querystring', async () => { + const params = { + dirId, + contentLength, + sourceAccount: 'source-account', + sourceAccountIdentifier: 'bob@cozy.localhost' + } + const result = await collection.createFile(data, params) + const expectedPath = `/files/${dirId}?Name=mydoc.epub&Type=file&Executable=false&Encrypted=false&MetadataID=&Size=${String( + contentLength + )}&SourceAccount=source-account&SourceAccountIdentifier=bob%40cozy.localhost&UpdatedAt=${new Date( data.lastModified ).toISOString()}&CreatedAt=${new Date(data.lastModified).toISOString()}` const expectedOptions = {