UNPKG

vtex

Version:

The platform for e-commerce apps

92 lines (91 loc) 4.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const axios_1 = tslib_1.__importDefault(require("axios")); const crypto_1 = require("crypto"); const jsonwebtoken_1 = tslib_1.__importDefault(require("jsonwebtoken")); const opn_1 = tslib_1.__importDefault(require("opn")); const path_1 = require("path"); const VTEXID_1 = require("../../../../api/clients/IOClients/external/VTEXID"); const storeUrl_1 = require("../../../../api/storeUrl"); const randomCryptoString_1 = require("../../../utils/randomCryptoString"); const spawnUnblockingChildProcess_1 = require("../../../utils/spawnUnblockingChildProcess"); const AuthProviderBase_1 = require("../AuthProviderBase"); const LoginServer_1 = require("./LoginServer"); class OAuthAuthenticator extends AuthProviderBase_1.AuthProviderBase { async login(account) { const secret = randomCryptoString_1.randomCryptoString(128, OAuthAuthenticator.SECRET_ALPHABET); const secretHash = this.hashSecret(secret); const vtexId = VTEXID_1.VTEXID.createClient({ account }); const loginServer = await LoginServer_1.LoginServer.create({ account, secret, }); try { const loginState = await vtexId.startToolbeltLogin({ account, secretHash, loopbackUrl: loginServer.loginCallbackUrl, }); loginServer.setLoginState(loginState); const url = await this.loginUrl(account, loginState); opn_1.default(url, { wait: false }); const token = await loginServer.token; const decodedToken = jsonwebtoken_1.default.decode(token); const login = decodedToken.sub; this.closeChromeTabIfMac(loginServer.loginCallbackUrl); return { login, token }; } finally { loginServer.close(); } } hashSecret(secret) { return crypto_1.createHash('sha256') .update(secret) .digest('base64'); } async loginUrl(account, loginState) { const hasAdminLogin = await this.hasAdminLoginInstalled(account); const returnUrl = `/api/vtexid/toolbelt/callback?state=${encodeURIComponent(loginState)}`; let loginPathPrefix; if (!hasAdminLogin) { // If for some reason vtex.admin-login is not installed in the account, fallback to use auth-server login url loginPathPrefix = storeUrl_1.storeUrl({ account, addWorkspace: false, path: OAuthAuthenticator.FALLBACK_AUTH_SERVER_LOGIN_URL_PATH, }); } else { loginPathPrefix = storeUrl_1.storeUrl({ account, addWorkspace: false, path: OAuthAuthenticator.ADMIN_LOGIN_URL_PATH }); } return `${loginPathPrefix}?returnUrl=${encodeURIComponent(returnUrl)}`; } async hasAdminLoginInstalled(account) { var _a; try { const { data } = await axios_1.default.get(storeUrl_1.storeUrl({ account, addWorkspace: false, path: '/_v/segment/admin-login/v1/login' })); return data.includes('vtex.admin-login'); } catch (err) { if (((_a = err.response) === null || _a === void 0 ? void 0 : _a.status) === 404) { return false; } throw err; } } closeChromeTabIfMac(loginCallbackUrl) { if (process.platform === 'darwin') { spawnUnblockingChildProcess_1.spawnUnblockingChildProcess('osascript', [ path_1.join(__dirname, '../../../../scripts/closeChrome.scpt'), loginCallbackUrl, ]); } } } exports.OAuthAuthenticator = OAuthAuthenticator; OAuthAuthenticator.AUTH_TYPE = 'oauth'; OAuthAuthenticator.SECRET_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~'; OAuthAuthenticator.ADMIN_LOGIN_URL_PATH = '/_v/segment/admin-login/v1/login'; OAuthAuthenticator.FALLBACK_AUTH_SERVER_LOGIN_URL_PATH = '/_v/private/auth-server/v1/login';