UNPKG

@pubby/sdk

Version:
323 lines (320 loc) 14.2 kB
import { __assign, __awaiter, __generator } from 'tslib'; import { localStorage } from '../../lib/polyfills.js'; import * as qs from 'qs'; import axios from 'axios'; import JwtDecode from 'jwt-decode'; var ClientCredentialsGrant = function (scopes) { if (scopes === void 0) { scopes = []; } return function (request) { return (__assign(__assign({}, request), { data: qs.stringify({ grant_type: "client_credentials", scope: scopes.join(" "), }) })); }; }; /** * Obtém um token utilizando login e senha * @param username nome de usuário * @param password senha * @param scopes escopos do token */ function PasswordGrant(username, password, scopes) { if (scopes === void 0) { scopes = []; } return function (request) { return (__assign(__assign({}, request), { data: qs.stringify({ grant_type: "password", username: username, password: password, scope: scopes.join(" "), }) })); }; } /** * Obtém um novo token de acesso utilizando um token de atualização * @param refreshToken token de atualização */ function RefreshTokenGrant(refreshToken) { return function (request) { return (__assign(__assign({}, request), { data: qs.stringify({ grant_type: "refresh_token", refresh_token: refreshToken, }) })); }; } /** * Obtém um novo ticket para conexão com o Socket.io * @param accessToken token de acesso */ function TicketGrant(accessToken) { return function (request) { return (__assign(__assign({}, request), { data: qs.stringify({ grant_type: "ticket", access_token: accessToken, }) })); }; } /** * Cria um cliente OAuth para gerenciar tokens */ var OAuthClient = /** @class */ (function () { function OAuthClient(options) { this.tokenRequest = null; this.offset = 0; this.delay = 3000; var _key = "pubby"; this.options = __assign({ storage: { get: function () { var _a; return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_b) { return [2 /*return*/, JSON.parse((_a = localStorage.getItem(_key)) !== null && _a !== void 0 ? _a : "{}")]; }); }); }, save: function (token) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { localStorage.setItem(_key, JSON.stringify(token)); return [2 /*return*/, token]; }); }); }, clear: function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { localStorage.removeItem(_key); return [2 /*return*/]; }); }); }, } }, options); } /** * Get current token from storage * @returns Access and refresh token */ OAuthClient.prototype.getToken = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.options.storage.get()]; }); }); }; OAuthClient.prototype.getTokenPayload = function () { return __awaiter(this, void 0, void 0, function () { var _a, err_1; return __generator(this, function (_b) { switch (_b.label) { case 0: _b.trys.push([0, 2, , 3]); _a = JwtDecode; return [4 /*yield*/, this.getToken()]; case 1: return [2 /*return*/, _a.apply(void 0, [(_b.sent()).accessToken])]; case 2: err_1 = _b.sent(); return [2 /*return*/, null]; case 3: return [2 /*return*/]; } }); }); }; OAuthClient.prototype.isTokenExpired = function () { var _a; return __awaiter(this, void 0, void 0, function () { var expires, offset, _b; return __generator(this, function (_c) { switch (_c.label) { case 0: return [4 /*yield*/, this.getToken()]; case 1: expires = (_c.sent()).expires; if (!((_a = this.offset) !== null && _a !== void 0)) return [3 /*break*/, 2]; _b = _a; return [3 /*break*/, 4]; case 2: return [4 /*yield*/, this.updateOffset()]; case 3: _b = (_c.sent()); _c.label = 4; case 4: offset = _b; return [2 /*return*/, Date.now() - offset + this.delay >= expires]; } }); }); }; OAuthClient.prototype.isAuthenticated = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getTokenPayload()]; case 1: if (!((_a.sent()) !== null)) return [3 /*break*/, 3]; return [4 /*yield*/, this.fetchOrRefreshAccessToken()]; case 2: _a.sent(); return [2 /*return*/, true]; case 3: return [2 /*return*/, false]; } }); }); }; OAuthClient.prototype.updateOffset = function () { return __awaiter(this, void 0, void 0, function () { var serverDate; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, axios .get(process.env.baseURL + "/oauth/time") .then(function (res) { return res.data.time; }) .catch(function () { return 0; })]; case 1: serverDate = _a.sent(); this.offset = Date.now() - serverDate; return [2 /*return*/, this.offset]; } }); }); }; OAuthClient.prototype.fetchOrRefreshAccessToken = function () { return __awaiter(this, void 0, void 0, function () { var token; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getToken()]; case 1: token = _a.sent(); if (!(token === null || token === void 0 ? void 0 : token.refreshToken)) { return [2 /*return*/, Promise.resolve(null)]; } if (!this.tokenRequest) { this.tokenRequest = new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () { var e_1; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); return [4 /*yield*/, this.isTokenExpired()]; case 1: if (_a.sent()) { resolve(this.refreshAccessToken().then(function (t) { return t.accessToken; })); } else { resolve(token === null || token === void 0 ? void 0 : token.accessToken); } return [3 /*break*/, 3]; case 2: e_1 = _a.sent(); reject(e_1); return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }).finally(function () { _this.tokenRequest = null; }); } return [2 /*return*/, this.tokenRequest]; } }); }); }; /** * Obtém um novo token de acesso utilizando uma granType customizado * @param grantType Função de grantType */ OAuthClient.prototype.requestToken = function (grantType) { var request = grantType({ method: "POST", baseURL: this.options.tokenUrl, headers: { "content-type": "application/x-www-form-urlencoded", }, auth: { username: this.options.clientId, password: this.options.clientSecret, }, }, __assign({}, this.options)); return axios(request).then(function (res) { return ({ accessToken: res.data.access_token, refreshToken: res.data.refresh_token, expires: Date.now() + res.data.expires * 1000, }); }); }; /** * Obtém um novo token de acesso utilizando uma granType customizado e salva no storage * @param grantType Função de grantType */ OAuthClient.prototype.requestTokenAndSave = function (grant) { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { return [2 /*return*/, this.requestToken(grant).then(function (token) { return _this.options.storage.save(token); })]; }); }); }; /** * Faz login e salva os tokens * @param username Nome de usuário * @param password Senha * @param scopes Escopos do token */ OAuthClient.prototype.login = function (username, password, scopes) { var _this = this; if (scopes === void 0) { scopes = []; } return this.requestToken(PasswordGrant(username, password, scopes)).then(function (token) { return _this.options.storage.save(token); }); }; /** * Revoga os tokens atuais e desconecta o usuário do socket */ OAuthClient.prototype.revoke = function () { return __awaiter(this, void 0, void 0, function () { var token; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getToken()]; case 1: token = _a.sent(); return [4 /*yield*/, axios({ method: "DELETE", baseURL: this.options.tokenUrl, headers: { "content-type": "application/x-www-form-urlencoded", authorization: "Bearer " + (token === null || token === void 0 ? void 0 : token.accessToken), "x-refresh-token": token === null || token === void 0 ? void 0 : token.refreshToken, }, })]; case 2: _a.sent(); return [2 /*return*/]; } }); }); }; /** * Atualiza os tokens e salva */ OAuthClient.prototype.refreshAccessToken = function () { return __awaiter(this, void 0, void 0, function () { var _a, _b; var _this = this; return __generator(this, function (_c) { switch (_c.label) { case 0: _a = this.requestTokenAndSave; _b = RefreshTokenGrant; return [4 /*yield*/, this.getToken()]; case 1: return [2 /*return*/, _a.apply(this, [_b.apply(void 0, [(_c.sent()).refreshToken])]).catch(function (err) { return __awaiter(_this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: if (!((_a = err.response) === null || _a === void 0 ? void 0 : _a.data.error)) return [3 /*break*/, 2]; return [4 /*yield*/, this.options.storage.clear()]; case 1: _b.sent(); _b.label = 2; case 2: return [2 /*return*/, Promise.reject(err)]; } }); }); })]; } }); }); }; return OAuthClient; }()); export { ClientCredentialsGrant, OAuthClient, PasswordGrant, RefreshTokenGrant, TicketGrant };