Skip to content

Commit

Permalink
fix: Support apiToken to be an async function: first request sends …
Browse files Browse the repository at this point in the history
…incorrect token
  • Loading branch information
paveltiunov committed Oct 23, 2019
1 parent e712ac6 commit a2d0c77
Show file tree
Hide file tree
Showing 7 changed files with 256 additions and 91 deletions.
1 change: 1 addition & 0 deletions docs/Cube.js-Frontend/@cubejs-client-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ API entry point.

- `apiToken` - [API token](security) is used to authorize requests and determine SQL database you're accessing.
In the development mode, Cube.js Backend will print the API token to the console on on startup.
Can be an async function without arguments that returns API token.
- `options` - options object.
- `options.apiUrl` - URL of your Cube.js Backend.
By default, in the development environment it is `http://localhost:4000/cubejs-api/v1`.
Expand Down
102 changes: 76 additions & 26 deletions packages/cubejs-client-core/dist/cubejs-client-core.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -842,7 +842,7 @@ function () {
this.apiToken = apiToken;
this.apiUrl = options.apiUrl || API_URL;
this.transport = options.transport || new HttpTransport({
authorization: apiToken,
authorization: typeof apiToken === 'function' ? undefined : apiToken,
apiUrl: this.apiUrl
});
this.pollInterval = options.pollInterval || 5;
Expand Down Expand Up @@ -872,7 +872,9 @@ function () {
options.mutexObj[mutexKey] = mutexValue;
}

var requestInstance = request();
var requestPromise = this.updateTransportAuthorization().then(function () {
return request();
});
var unsubscribed = false;

var checkMutex =
Expand All @@ -881,29 +883,36 @@ function () {
var _ref = _asyncToGenerator(
/*#__PURE__*/
_regeneratorRuntime.mark(function _callee() {
var requestInstance;
return _regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return requestPromise;

case 2:
requestInstance = _context.sent;

if (!(options.mutexObj && options.mutexObj[mutexKey] !== mutexValue)) {
_context.next = 6;
_context.next = 9;
break;
}

unsubscribed = true;

if (!requestInstance.unsubscribe) {
_context.next = 5;
_context.next = 8;
break;
}

_context.next = 5;
_context.next = 8;
return requestInstance.unsubscribe();

case 5:
case 8:
throw MUTEX_ERROR;

case 6:
case 9:
case "end":
return _context.stop();
}
Expand All @@ -922,11 +931,17 @@ function () {
var _ref2 = _asyncToGenerator(
/*#__PURE__*/
_regeneratorRuntime.mark(function _callee4(response, next) {
var subscribeNext, continueWait, token, body, error, result;
var requestInstance, subscribeNext, continueWait, body, error, result;
return _regeneratorRuntime.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
_context4.next = 2;
return requestPromise;

case 2:
requestInstance = _context4.sent;

subscribeNext =
/*#__PURE__*/
function () {
Expand Down Expand Up @@ -1022,20 +1037,8 @@ function () {
};
}();

if (!(typeof _this.apiToken === 'function')) {
_context4.next = 7;
break;
}

_context4.next = 5;
return _this.apiToken();

case 5:
token = _context4.sent;

if (_this.transport.authorization !== token) {
_this.transport.authorization = token;
}
_context4.next = 7;
return _this.updateTransportAuthorization();

case 7:
if (!(response.status === 502)) {
Expand Down Expand Up @@ -1151,31 +1154,39 @@ function () {
};
}();

var promise = mutexPromise(requestInstance.subscribe(loadImpl));
var promise = requestPromise.then(function (requestInstance) {
return mutexPromise(requestInstance.subscribe(loadImpl));
});

if (callback) {
return {
unsubscribe: function () {
var _unsubscribe = _asyncToGenerator(
/*#__PURE__*/
_regeneratorRuntime.mark(function _callee5() {
var requestInstance;
return _regeneratorRuntime.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
_context5.next = 2;
return requestPromise;

case 2:
requestInstance = _context5.sent;
unsubscribed = true;

if (!requestInstance.unsubscribe) {
_context5.next = 3;
_context5.next = 6;
break;
}

return _context5.abrupt("return", requestInstance.unsubscribe());

case 3:
case 6:
return _context5.abrupt("return", null);

case 4:
case 7:
case "end":
return _context5.stop();
}
Expand All @@ -1192,6 +1203,44 @@ function () {
return promise;
}
}
}, {
key: "updateTransportAuthorization",
value: function () {
var _updateTransportAuthorization = _asyncToGenerator(
/*#__PURE__*/
_regeneratorRuntime.mark(function _callee6() {
var token;
return _regeneratorRuntime.wrap(function _callee6$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
if (!(typeof this.apiToken === 'function')) {
_context6.next = 5;
break;
}

_context6.next = 3;
return this.apiToken();

case 3:
token = _context6.sent;

if (this.transport.authorization !== token) {
this.transport.authorization = token;
}

case 5:
case "end":
return _context6.stop();
}
}
}, _callee6, this);
}));

return function updateTransportAuthorization() {
return _updateTransportAuthorization.apply(this, arguments);
};
}()
/**
* Fetch data for passed `query`.
*
Expand Down Expand Up @@ -1306,6 +1355,7 @@ function () {
* @name cubejs
* @param apiToken - [API token](security) is used to authorize requests and determine SQL database you're accessing.
* In the development mode, Cube.js Backend will print the API token to the console on on startup.
* Can be an async function without arguments that returns API token.
* @param options - options object.
* @param options.apiUrl - URL of your Cube.js Backend.
* By default, in the development environment it is `http://localhost:4000/cubejs-api/v1`.
Expand Down
Loading

0 comments on commit a2d0c77

Please sign in to comment.