Skip to content

Commit 7e2772b

Browse files
Brent1LTBrent Bumann
andauthored
Add cookie auth and custom header feature (#814)
Co-authored-by: Brent Bumann <bbumann@dropbox.com>
1 parent b851e70 commit 7e2772b

File tree

6 files changed

+74
-1
lines changed

6 files changed

+74
-1
lines changed

generator/typescript/index.d.tstemplate

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ export interface DropboxOptions {
177177
domain?: string;
178178
// A custom delimiter to use when separating domain subdomain. This should only be used for testing as scaffolding.
179179
domainDelimiter?: string;
180+
// An object (in the form of header: value) designed to set custom headers to use during a request.
181+
customHeaders?: object;
180182
}
181183

182184
export class DropboxResponseError<T> {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dropbox",
3-
"version": "10.11.0",
3+
"version": "10.12.0",
44
"registry": "npm",
55
"description": "The Dropbox JavaScript SDK is a lightweight, promise based interface to the Dropbox v2 API that works in both nodejs and browser environments.",
66
"main": "cjs/index.js",

src/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const APP_AUTH = 'app';
66
export const USER_AUTH = 'user';
77
export const TEAM_AUTH = 'team';
88
export const NO_AUTH = 'noauth';
9+
export const COOKIE = 'cookie';
910

1011
export const DEFAULT_API_DOMAIN = 'dropboxapi.com';
1112
export const DEFAULT_DOMAIN = 'dropbox.com';

src/dropbox.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
TEAM_AUTH,
77
USER_AUTH,
88
NO_AUTH,
9+
COOKIE,
910
} from './constants.js';
1011
import { routes } from '../lib/routes.js';
1112
import DropboxAuth from './auth.js';
@@ -50,6 +51,8 @@ const b64 = typeof btoa === 'undefined'
5051
* should only be used for testing as scaffolding to avoid making network requests.
5152
* @arg {String} [options.domainDelimiter] - A custom delimiter to use when separating domain from
5253
* subdomain. This should only be used for testing as scaffolding.
54+
* @arg {Object} [options.customHeaders] - An object (in the form of header: value) designed to set
55+
* custom headers to use during a request.
5356
*/
5457
export default class Dropbox {
5558
constructor(options) {
@@ -68,6 +71,7 @@ export default class Dropbox {
6871

6972
this.domain = options.domain;
7073
this.domainDelimiter = options.domainDelimiter;
74+
this.customHeaders = options.customHeaders;
7175

7276
Object.assign(this, routes);
7377
}
@@ -125,6 +129,8 @@ export default class Dropbox {
125129
break;
126130
case NO_AUTH:
127131
break;
132+
case COOKIE:
133+
break;
128134
default:
129135
throw new Error(`Unhandled auth type: ${auth}`);
130136
}
@@ -206,5 +212,11 @@ export default class Dropbox {
206212
if (this.pathRoot) {
207213
options.headers['Dropbox-API-Path-Root'] = this.pathRoot;
208214
}
215+
if (this.customHeaders) {
216+
const headerKeys = Object.keys(this.customHeaders);
217+
headerKeys.forEach((header) => {
218+
options.headers[header] = this.customHeaders[header];
219+
});
220+
}
209221
}
210222
}

test/unit/dropbox.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
TEAM_AUTH,
1212
APP_AUTH,
1313
NO_AUTH,
14+
COOKIE,
1415
} from '../../src/constants.js';
1516
import { Dropbox, DropboxAuth } from '../../index.js';
1617

@@ -28,6 +29,18 @@ describe('Dropbox', () => {
2829
});
2930
});
3031

32+
describe('customHeaders', () => {
33+
it('can be set in the constructor', () => {
34+
const dbx = new Dropbox({ customHeaders: { foo: 'bar' } });
35+
chai.assert.equal(dbx.customHeaders.foo, 'bar');
36+
});
37+
38+
it('is undefined if not set in constructor', () => {
39+
const dbx = new Dropbox();
40+
chai.assert.equal(dbx.customHeaders, undefined);
41+
});
42+
});
43+
3144
describe('RPC requests', () => {
3245
it('request() calls the correct request method', () => {
3346
const dbx = new Dropbox();
@@ -86,6 +99,20 @@ describe('Dropbox', () => {
8699
chai.assert.equal(APP_AUTH, dbx.rpcRequest.getCall(0).args[2]);
87100
});
88101

102+
it('completes a cookie auth RPC request', () => {
103+
const dbxAuth = new DropboxAuth();
104+
const dbx = new Dropbox({ auth: dbxAuth });
105+
const rpcSpy = sinon.spy(dbx, 'rpcRequest');
106+
dbx.request('path', {}, COOKIE, 'api', RPC)
107+
.catch((error) => {
108+
fail(error);
109+
});
110+
chai.assert.isTrue(rpcSpy.calledOnce);
111+
chai.assert.equal('path', dbx.rpcRequest.getCall(0).args[0]);
112+
chai.assert.deepEqual({}, dbx.rpcRequest.getCall(0).args[1]);
113+
chai.assert.equal(COOKIE, dbx.rpcRequest.getCall(0).args[2]);
114+
});
115+
89116
it('throws an error for invalid request styles', () => {
90117
chai.assert.throws(
91118
Dropbox.prototype.request.bind(Dropbox, '', {}, 'user', 'api', 'BADTYPE'),
@@ -120,6 +147,10 @@ describe('Dropbox', () => {
120147
const dbx = new Dropbox();
121148
return chai.assert.isRejected(dbx.uploadRequest('path', {}, NO_AUTH, 'api'), Error, `Unexpected auth type: ${NO_AUTH}`);
122149
});
150+
it('throws an error for cookie auth', () => {
151+
const dbx = new Dropbox();
152+
return chai.assert.isRejected(dbx.uploadRequest('path', {}, COOKIE, 'api'), Error, `Unexpected auth type: ${COOKIE}`);
153+
});
123154
});
124155

125156
describe('Download Requests', () => {
@@ -149,6 +180,11 @@ describe('Dropbox', () => {
149180
const dbx = new Dropbox();
150181
return chai.assert.isRejected(dbx.downloadRequest('path', {}, NO_AUTH, 'api'), Error, `Unexpected auth type: ${NO_AUTH}`);
151182
});
183+
184+
it('throws an error for cookie auth', () => {
185+
const dbx = new Dropbox();
186+
return chai.assert.isRejected(dbx.downloadRequest('path', {}, COOKIE, 'api'), Error, `Unexpected auth type: ${COOKIE}`);
187+
});
152188
});
153189

154190
describe('pathRoot', () => {
@@ -186,5 +222,25 @@ describe('Dropbox', () => {
186222
}
187223
}
188224
});
225+
226+
it('sets custom headers correctly', () => {
227+
const dbx = new Dropbox({
228+
customHeaders: {
229+
foo: 'bar',
230+
milk: 'shake',
231+
cookie: 'hash',
232+
},
233+
});
234+
235+
const fetchOptions = {
236+
headers: {},
237+
};
238+
239+
dbx.setCommonHeaders(fetchOptions);
240+
const { headers } = fetchOptions;
241+
chai.assert.equal(headers.foo, 'bar');
242+
chai.assert.equal(headers.milk, 'shake');
243+
chai.assert.equal(headers.cookie, 'hash');
244+
});
189245
});
190246
});

types/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ export interface DropboxOptions {
178178
domain?: string;
179179
// A custom delimiter to use when separating domain subdomain. This should only be used for testing as scaffolding.
180180
domainDelimiter?: string;
181+
// An object (in the form of header: value) designed to set custom headers to use during a request.
182+
customHeaders?: object;
181183
}
182184

183185
export class DropboxResponseError<T> {

0 commit comments

Comments
 (0)