@netology-group/account
Version:
account client
242 lines (209 loc) • 9.88 kB
JavaScript
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import { fetchRetry, isExpired, getExpiresTime, validResponse, parsedResponse, parse } from './utils/index';
var MAX_AJAX_RETRY = 3;
var AJAX_RETRY_DELAY = 1000;
var LEEWAY = 3000;
export var Account =
/*#__PURE__*/
function () {
function Account(config, provider, storage) {
_classCallCheck(this, Account);
_defineProperty(this, "fetchFn", void 0);
_defineProperty(this, "fetchOpts", void 0);
_defineProperty(this, "id", void 0);
_defineProperty(this, "label", void 0);
_defineProperty(this, "leeway", void 0);
_defineProperty(this, "requestMode", void 0);
_defineProperty(this, "provider", void 0);
_defineProperty(this, "retries", void 0);
_defineProperty(this, "retryDelay", void 0);
_defineProperty(this, "storage", void 0);
if (!config) throw new TypeError('Missing `config`');
if (!provider) throw new TypeError('Provider is not defined');
if (!storage) throw new TypeError('Storage is not defined');
this.storage = storage;
this.provider = provider;
this.fetchFn = fetchRetry;
this.fetchOpts = {
delay: config.retryDelay || AJAX_RETRY_DELAY,
retries: config.retries || MAX_AJAX_RETRY
};
this.leeway = config.leeway || LEEWAY;
this.requestMode = config.requestMode || 'id';
var _this$_createId = this._createId(config.audience, config.label),
id = _this$_createId.id,
label = _this$_createId.label;
this.label = label;
this.id = id;
if (!this.id) throw new TypeError('Failed to configure account. Id is not present');
} // eslint-disable-next-line max-len
_createClass(Account, [{
key: "_createId",
// eslint-disable-next-line class-methods-use-this
value: function _createId(audience, label) {
var separator = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '.';
if (!audience) throw new TypeError('`audience` is absent');
if (!label) throw new TypeError('`label` is absent');
return {
id: "".concat(label).concat(separator).concat(audience),
label: label
};
}
}, {
key: "_requestLabel",
value: function _requestLabel() {
return this.requestMode === 'label' ? this.label : this.id;
}
}, {
key: "load",
value: function load() {
var _this = this;
var storageLabel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var label = storageLabel || this.id;
if (!label) return Promise.reject(new TypeError('`label` is absent'));
return Promise.resolve(function () {
return _this.storage.getItem(label);
}).then(function (fn) {
var value = fn();
if (!value) throw new TypeError('Could not load data');
return parse(value);
});
}
}, {
key: "remove",
value: function remove() {
var _this2 = this;
var storageLabel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var label = storageLabel || this.id;
if (!label) return Promise.reject(new TypeError('`label` is absent'));
return this.load(label).then(function (tokenData) {
_this2.storage.removeItem(label);
return tokenData;
});
}
}, {
key: "store",
value: function store(data) {
var storageLabel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
if (!data) throw new TypeError('`token` is absent');
var accessExists = Object.prototype.hasOwnProperty.call(data, 'access_token');
var refreshExists = Object.prototype.hasOwnProperty.call(data, 'refresh_token');
if (!accessExists) throw new TypeError('`access_token` is absent');
if (refreshExists && !data.refresh_token) throw new TypeError('`refresh_token` is absent');
if (!refreshExists && !data.access_token) throw new TypeError('`access_token` is absent');
return this._store(data, storageLabel);
}
}, {
key: "_store",
value: function _store(data) {
var _this3 = this;
var storageLabel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
var label = storageLabel || this.id;
if (!label) return Promise.reject(new TypeError('`label` is absent'));
var token = {
access_token: data.access_token,
refresh_token: data.refresh_token,
expires_time: data.expires_time || 0
};
return Promise.resolve(token).then(function (tokenData) {
_this3.storage.setItem(label, JSON.stringify(tokenData));
return tokenData;
});
}
}, {
key: "account",
value: function account() {
var _this4 = this;
var storageLabel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var label = storageLabel || this.id;
var fn = this.provider.account;
return this.tokenData(label).then(function (data) {
var access_token = data.access_token;
return [_this4._requestLabel(), access_token];
}).then(function (req) {
return _this4.fetchFn(function () {
return fn.call.apply(fn, [_this4.provider].concat(_toConsumableArray(req)));
}, _this4.fetchOpts);
}).then(validResponse).then(parsedResponse);
}
}, {
key: "tokenData",
value: function tokenData() {
var _this5 = this;
var storageLabel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var label = storageLabel || this.id;
var fn = this.provider.refreshAccessToken;
return this.load(label).then(function (maybeValidTokens) {
var expired = isExpired(maybeValidTokens, Date.now(), _this5.leeway);
if (!expired) return maybeValidTokens;
var refresh_token = maybeValidTokens.refresh_token; // eslint-disable-next-line promise/no-nesting
return Promise.resolve([_this5._requestLabel(), refresh_token]).then(function (req) {
return _this5.fetchFn(function () {
return fn.call.apply(fn, [_this5.provider].concat(_toConsumableArray(req)));
}, _this5.fetchOpts);
}).then(validResponse).then(parsedResponse) // eslint-disable-next-line promise/no-nesting
.then(function (_) {
return _this5.load(label).then(function (old) {
return _this5.store({
access_token: _.access_token,
refresh_token: old.refresh_token,
expires_time: getExpiresTime(_.expires_in, Date.now())
});
});
});
});
}
}, {
key: "revokeRefreshToken",
value: function revokeRefreshToken() {
var _this6 = this;
var storageLabel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var label = storageLabel || this.id;
var fn = this.provider.revokeRefreshToken;
return this.load(label).then(function (maybeToken) {
var refresh_token = maybeToken.refresh_token;
return [_this6._requestLabel(), refresh_token];
}).then(function (req) {
return _this6.fetchFn(function () {
return fn.call.apply(fn, [_this6.provider].concat(_toConsumableArray(req)));
}, _this6.fetchOpts);
}).then(validResponse).then(parsedResponse) // eslint-disable-next-line promise/no-nesting
.then(function (_) {
return _this6.load(label).then(function (old) {
return _this6.store({
access_token: old.access_token,
refresh_token: _.refresh_token,
expires_time: old.expires_time
});
});
});
}
}], [{
key: "fetchLabel",
value: function fetchLabel(data, provider, label) {
var refresh_token = data.refresh_token;
if (!refresh_token) throw new TypeError('`refresh_token` is absent');
if (!provider) throw new TypeError('Provider is not defined');
var fetchOpts = {
delay: AJAX_RETRY_DELAY,
retries: MAX_AJAX_RETRY
};
return fetchRetry(function () {
return provider.refreshAccessToken(label || 'me', refresh_token);
}, fetchOpts).then(validResponse).then(parsedResponse) // eslint-disable-next-line promise/no-nesting
.then(function (tokenData) {
return fetchRetry(function () {
return provider.account(label || 'me', tokenData.access_token);
}, fetchOpts).then(validResponse).then(parsedResponse);
});
}
}]);
return Account;
}();