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 30, 2021
1 parent b851e70 commit 77b9bf8
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 0 deletions.
2 changes: 2 additions & 0 deletions generator/typescript/index.d.tstemplate
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ export interface DropboxOptions {
domain?: string;
// A custom delimiter to use when separating domain subdomain. This should only be used for testing as scaffolding.
domainDelimiter?: string;
// An object (in the form of header: value) designed to set custom headers to use during a request.
customHeaders?: object;
}

export class DropboxResponseError<T> {
Expand Down
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
12 changes: 12 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 (in the form of header: value) 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,8 @@ export default class Dropbox {
break;
case NO_AUTH:
break;
case COOKIE:
break;
default:
throw new Error(`Unhandled auth type: ${auth}`);
}
Expand Down Expand Up @@ -206,5 +212,11 @@ export default class Dropbox {
if (this.pathRoot) {
options.headers['Dropbox-API-Path-Root'] = this.pathRoot;
}
if (this.customHeaders) {
const headerKeys = Object.keys(this.customHeaders);
headerKeys.forEach((header) => {
options.headers[header] = this.customHeaders[header];
});
}
}
}
56 changes: 56 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,20 @@ describe('Dropbox', () => {
chai.assert.equal(APP_AUTH, dbx.rpcRequest.getCall(0).args[2]);
});

it('completes a cookie auth RPC request', () => {
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('throws an error for invalid request styles', () => {
chai.assert.throws(
Dropbox.prototype.request.bind(Dropbox, '', {}, 'user', 'api', 'BADTYPE'),
Expand Down Expand Up @@ -120,6 +147,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 +180,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 +222,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');
});
});
});
2 changes: 2 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ export interface DropboxOptions {
domain?: string;
// A custom delimiter to use when separating domain subdomain. This should only be used for testing as scaffolding.
domainDelimiter?: string;
// An object (in the form of header: value) designed to set custom headers to use during a request.
customHeaders?: object;
}

export class DropboxResponseError<T> {
Expand Down

0 comments on commit 77b9bf8

Please sign in to comment.