Skip to content

Commit

Permalink
Add cookie auth and custom header feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Brent Bumann committed Sep 29, 2021
1 parent b999efb commit 48e9b05
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const APP_AUTH = 'app';
export const USER_AUTH = 'user';
export const TEAM_AUTH = 'team';
export const NO_AUTH = 'noauth';
export const COOKIE = 'cookie';

export const DEFAULT_API_DOMAIN = 'dropboxapi.com';
export const DEFAULT_DOMAIN = 'dropbox.com';
Expand Down
14 changes: 14 additions & 0 deletions src/dropbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
TEAM_AUTH,
USER_AUTH,
NO_AUTH,
COOKIE,
} from './constants.js';
import { routes } from '../lib/routes.js';
import DropboxAuth from './auth.js';
Expand Down Expand Up @@ -50,6 +51,8 @@ const b64 = typeof btoa === 'undefined'
* should only be used for testing as scaffolding to avoid making network requests.
* @arg {String} [options.domainDelimiter] - A custom delimiter to use when separating domain from
* subdomain. This should only be used for testing as scaffolding.
* @arg {Object} [options.customHeaders] - An object designed to set custom headers to use
* during a request.
*/
export default class Dropbox {
constructor(options) {
Expand All @@ -68,6 +71,7 @@ export default class Dropbox {

this.domain = options.domain;
this.domainDelimiter = options.domainDelimiter;
this.customHeaders = options.customHeaders;

Object.assign(this, routes);
}
Expand Down Expand Up @@ -125,6 +129,11 @@ export default class Dropbox {
break;
case NO_AUTH:
break;
case COOKIE:
if (this.auth.accessToken) {
throw new Error('Can\'t use access tokens with cookie auth');
}
break;
default:
throw new Error(`Unhandled auth type: ${auth}`);
}
Expand Down Expand Up @@ -206,5 +215,10 @@ export default class Dropbox {
if (this.pathRoot) {
options.headers['Dropbox-API-Path-Root'] = this.pathRoot;
}
if (this.customHeaders) {
for (const header in this.customHeaders) {
options.headers[header] = this.customHeaders[header];
}
}
}
}
62 changes: 62 additions & 0 deletions test/unit/dropbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
TEAM_AUTH,
APP_AUTH,
NO_AUTH,
COOKIE,
} from '../../src/constants.js';
import { Dropbox, DropboxAuth } from '../../index.js';

Expand All @@ -28,6 +29,18 @@ describe('Dropbox', () => {
});
});

describe('customHeaders', () => {
it('can be set in the constructor', () => {
const dbx = new Dropbox({ customHeaders: { foo: 'bar' } });
chai.assert.equal(dbx.customHeaders.foo, 'bar');
});

it('is undefined if not set in constructor', () => {
const dbx = new Dropbox();
chai.assert.equal(dbx.customHeaders, undefined);
});
});

describe('RPC requests', () => {
it('request() calls the correct request method', () => {
const dbx = new Dropbox();
Expand Down Expand Up @@ -86,6 +99,26 @@ describe('Dropbox', () => {
chai.assert.equal(APP_AUTH, dbx.rpcRequest.getCall(0).args[2]);
});

it('completes a cookie auth RPC request when not supplied an access token', () => {
const dbxAuth = new DropboxAuth();
const dbx = new Dropbox({ auth: dbxAuth });
const rpcSpy = sinon.spy(dbx, 'rpcRequest');
dbx.request('path', {}, COOKIE, 'api', RPC)
.catch((error) => {
fail(error);
});
chai.assert.isTrue(rpcSpy.calledOnce);
chai.assert.equal('path', dbx.rpcRequest.getCall(0).args[0]);
chai.assert.deepEqual({}, dbx.rpcRequest.getCall(0).args[1]);
chai.assert.equal(COOKIE, dbx.rpcRequest.getCall(0).args[2]);
});

it('errors if cookie auth is supplied an OAuth token', () => {
const dbxAuth = new DropboxAuth({ accessToken: 'foo' });
const dbx = new Dropbox({ auth: dbxAuth });
return chai.assert.isRejected(dbx.rpcRequest('path', {}, COOKIE, 'api'), Error, 'Can\'t use access tokens with cookie auth');
});

it('throws an error for invalid request styles', () => {
chai.assert.throws(
Dropbox.prototype.request.bind(Dropbox, '', {}, 'user', 'api', 'BADTYPE'),
Expand Down Expand Up @@ -120,6 +153,10 @@ describe('Dropbox', () => {
const dbx = new Dropbox();
return chai.assert.isRejected(dbx.uploadRequest('path', {}, NO_AUTH, 'api'), Error, `Unexpected auth type: ${NO_AUTH}`);
});
it('throws an error for cookie auth', () => {
const dbx = new Dropbox();
return chai.assert.isRejected(dbx.uploadRequest('path', {}, COOKIE, 'api'), Error, `Unexpected auth type: ${COOKIE}`);
});
});

describe('Download Requests', () => {
Expand Down Expand Up @@ -149,6 +186,11 @@ describe('Dropbox', () => {
const dbx = new Dropbox();
return chai.assert.isRejected(dbx.downloadRequest('path', {}, NO_AUTH, 'api'), Error, `Unexpected auth type: ${NO_AUTH}`);
});

it('throws an error for cookie auth', () => {
const dbx = new Dropbox();
return chai.assert.isRejected(dbx.downloadRequest('path', {}, COOKIE, 'api'), Error, `Unexpected auth type: ${COOKIE}`);
});
});

describe('pathRoot', () => {
Expand Down Expand Up @@ -186,5 +228,25 @@ describe('Dropbox', () => {
}
}
});

it('sets custom headers correctly', () => {
const dbx = new Dropbox({
customHeaders: {
foo: 'bar',
milk: 'shake',
cookie: 'hash',
},
});

const fetchOptions = {
headers: {},
};

dbx.setCommonHeaders(fetchOptions);
const { headers } = fetchOptions;
chai.assert.equal(headers.foo, 'bar');
chai.assert.equal(headers.milk, 'shake');
chai.assert.equal(headers.cookie, 'hash');
});
});
});

0 comments on commit 48e9b05

Please sign in to comment.