From 45703281f9a5a6f6b82845a5596f34e84079c112 Mon Sep 17 00:00:00 2001 From: naugtur Date: Tue, 7 Jul 2020 11:16:58 +0200 Subject: [PATCH] Generalize authorize function, add file and role operations --- lib/index.js | 132 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 106 insertions(+), 26 deletions(-) diff --git a/lib/index.js b/lib/index.js index cb9e07a..caf4719 100644 --- a/lib/index.js +++ b/lib/index.js @@ -10,23 +10,28 @@ const getGUID = () => { }) } +const must = required => { + Object.keys(required).forEach(key => { + if (required[key] === undefined) { + throw Error(`'${key} option is required`) + } + }) +} + class Sharepoint { constructor (url) { - if (!url) { - throw new Error('You must provide a url.') - } + must({ url }) this.url = url this.headers = null this.site = null } - async authenticate (username, password) { - if (!username && !password) { - throw new Error('You must provide a username and password.') + async authenticate (credentials) { + if (!credentials) { + throw Error('Credentials are required') } - - const { headers } = await spauth.getAuth(this.url, { username, password }) + const { headers } = await spauth.getAuth(this.url, credentials) this.headers = { ...headers, Accept: 'application/json;odata=verbose' @@ -59,6 +64,8 @@ class Sharepoint { serverRelativeUrl: site.ServerRelativeUrl, lastModified: site.LastItemUserModifiedDate } + + return site } async getFormDigestValue () { @@ -96,13 +103,33 @@ class Sharepoint { return [...folders.data.d.results, ...files.data.d.results] } + async getFileMeta ({ path, fileName }) { + this.checkHeaders() + + const { url, headers, site } = this + + return await axios.get( + `${url}/_api/web/GetFolderByServerRelativeUrl('${site.serverRelativeUrl}${path}')/Files('${fileName}')`, + { headers, responseType: 'json' } + ) + } + + async getFileData ({ path, fileName }) { + this.checkHeaders() + + const { url, headers, site } = this + + return await axios.get( + `${url}/_api/web/GetFolderByServerRelativeUrl('${site.serverRelativeUrl}${path}')/Files('${fileName}')/$value`, + { headers, responseType: 'stream' } + ) + } + async createFolder (path) { this.checkHeaders() const formDigestValue = await this.getFormDigestValue() - if (!path) { - throw new Error('You must provide a path.') - } + must({ path }) await axios({ method: 'post', @@ -124,9 +151,7 @@ class Sharepoint { this.checkHeaders() const formDigestValue = await this.getFormDigestValue() - if (!path) { - throw new Error('You must provide a path.') - } + must({ path }) await axios({ method: 'post', @@ -143,24 +168,25 @@ class Sharepoint { this.checkHeaders() const formDigestValue = await this.getFormDigestValue() - const { path, fileName, data } = options + const { path, fileName, data, size } = options + + must({ fileName, data }) - if (!fileName) { - throw new Error('You must provide a file name.') + const headers = { + ...this.headers, + 'X-RequestDigest': formDigestValue } - if (!data) { - throw new Error('You must provide data.') + // necessary for streams in some cases - axios may default to transfer-encoding: chunked if not provided the size + if (size) { + headers['content-length'] = size } await axios({ method: 'post', url: `${this.url}/_api/web/GetFolderByServerRelativeUrl('${this.site.serverRelativeUrl}${path}')/Files/add(url='${fileName}', overwrite=true)`, data, - headers: { - ...this.headers, - 'X-RequestDigest': formDigestValue - } + headers }) } @@ -261,9 +287,7 @@ class Sharepoint { const { path, fileName } = options - if (!fileName) { - throw new Error('You must provide a file name.') - } + must({ fileName }) await axios({ method: 'post', @@ -275,6 +299,62 @@ class Sharepoint { } }) } + + async deleteRole (options) { + this.checkHeaders() + const formDigestValue = await this.getFormDigestValue() + + const { path, fileName, principalid } = options + + must({ fileName, principalid }) + + return await axios({ + method: 'post', + url: `${this.url}/_api/web/GetFileByServerRelativeUrl('${this.site.serverRelativeUrl}${path}/${fileName}')/ListItemAllFields/roleassignments/getbyprincipalid(${principalid})`, + headers: { + ...this.headers, + 'X-RequestDigest': formDigestValue, + 'X-HTTP-Method': 'DELETE' + } + }) + } + + async addRole (options) { + this.checkHeaders() + const formDigestValue = await this.getFormDigestValue() + + const { path, fileName, rolefid, principalid } = options + + must({ fileName, rolefid, principalid }) + return await axios({ + method: 'post', + url: `${this.url}/_api/web/GetFileByServerRelativeUrl('${this.site.serverRelativeUrl}${path}/${fileName}')/ListItemAllFields/roleassignments/addroleassignment(principalid=${principalid},roledefid=${rolefid})`, + headers: { + ...this.headers, + 'X-RequestDigest': formDigestValue, + 'X-HTTP-Method': 'DELETE' + } + }) + } + + async breakRoleInheritance (options) { + this.checkHeaders() + const formDigestValue = await this.getFormDigestValue() + + const { path, fileName } = options + + must({ fileName }) + + return await axios({ + method: 'post', + url: `${this.url}/_api/web/GetFileByServerRelativeUrl('${this.site.serverRelativeUrl}${path}/${fileName}')/ListItemAllFields/breakroleinheritance(true)`, + headers: { + ...this.headers, + Accept: 'application/json;odata=verbose', + 'X-RequestDigest': formDigestValue + } + }) + } } module.exports = Sharepoint