UNPKG

@redocly/openapi-core

Version:

See https://github.com/Redocly/openapi-cli

170 lines (169 loc) 7.74 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.isRedoclyRegistryURL = exports.RedoclyClient = void 0; const fs_1 = require("fs"); const path_1 = require("path"); const os_1 = require("os"); const colorette_1 = require("colorette"); const registry_api_1 = require("./registry-api"); const config_1 = require("../config/config"); const utils_1 = require("../utils"); const TOKEN_FILENAME = '.redocly-config.json'; let REDOCLY_DOMAIN; // workaround for the isRedoclyRegistryURL, see more below class RedoclyClient { constructor(region) { this.accessTokens = {}; this.region = this.loadRegion(region); this.loadTokens(); this.domain = region ? config_1.DOMAINS[region] : process.env.REDOCLY_DOMAIN || config_1.DOMAINS[config_1.DEFAULT_REGION]; /* * We can't use process.env here because it is replaced by a const in some client-side bundles, * which breaks assignment. */ REDOCLY_DOMAIN = this.domain; // isRedoclyRegistryURL depends on the value to be set this.registryApi = new registry_api_1.RegistryApi(this.accessTokens, this.region); } loadRegion(region) { if (region && !config_1.DOMAINS[region]) { process.stdout.write(colorette_1.red(`Invalid argument: region in config file.\nGiven: ${colorette_1.green(region)}, choices: "us", "eu".\n`)); process.exit(1); } if (process.env.REDOCLY_DOMAIN) { return (config_1.AVAILABLE_REGIONS.find((region) => config_1.DOMAINS[region] === process.env.REDOCLY_DOMAIN) || config_1.DEFAULT_REGION); } return region || config_1.DEFAULT_REGION; } getRegion() { return this.region; } hasTokens() { return utils_1.isNotEmptyObject(this.accessTokens); } // <backward compatibility: old versions of portal> hasToken() { return !!this.accessTokens[this.region]; } getAuthorizationHeader() { return __awaiter(this, void 0, void 0, function* () { const token = this.accessTokens[this.region]; // print this only if there is token but invalid if (token && !this.isAuthorizedWithRedoclyByRegion()) { process.stderr.write(`${colorette_1.yellow('Warning:')} invalid Redocly API key. Use "npx @redocly/openapi-cli login" to provide your API key\n`); return undefined; } return token; }); } // </backward compatibility: portal> setAccessTokens(accessTokens) { this.accessTokens = accessTokens; } loadTokens() { const credentialsPath = path_1.resolve(os_1.homedir(), TOKEN_FILENAME); const credentials = this.readCredentialsFile(credentialsPath); if (utils_1.isNotEmptyObject(credentials)) { this.setAccessTokens(Object.assign(Object.assign({}, credentials), (credentials.token && !credentials[this.region] && { [this.region]: credentials.token, }))); } if (process.env.REDOCLY_AUTHORIZATION) { this.setAccessTokens(Object.assign(Object.assign({}, this.accessTokens), { [this.region]: process.env.REDOCLY_AUTHORIZATION })); } } getAllTokens() { return Object.entries(this.accessTokens) .filter(([region]) => config_1.AVAILABLE_REGIONS.includes(region)) .map(([region, token]) => ({ region, token })); } getValidTokens() { return __awaiter(this, void 0, void 0, function* () { const allTokens = this.getAllTokens(); const verifiedTokens = yield Promise.allSettled(allTokens.map(({ token, region }) => this.verifyToken(token, region))); return allTokens .filter((_, index) => verifiedTokens[index].status === 'fulfilled') .map(({ token, region }) => ({ token, region, valid: true })); }); } getTokens() { return __awaiter(this, void 0, void 0, function* () { return this.hasTokens() ? yield this.getValidTokens() : []; }); } isAuthorizedWithRedoclyByRegion() { return __awaiter(this, void 0, void 0, function* () { if (!this.hasTokens()) { return false; } const accessToken = this.accessTokens[this.region]; if (!accessToken) { return false; } try { yield this.verifyToken(accessToken, this.region); return true; } catch (err) { return false; } }); } isAuthorizedWithRedocly() { return __awaiter(this, void 0, void 0, function* () { return this.hasTokens() && utils_1.isNotEmptyObject(yield this.getValidTokens()); }); } readCredentialsFile(credentialsPath) { return fs_1.existsSync(credentialsPath) ? JSON.parse(fs_1.readFileSync(credentialsPath, 'utf-8')) : {}; } verifyToken(accessToken, region, verbose = false) { return __awaiter(this, void 0, void 0, function* () { return this.registryApi.authStatus(accessToken, region, verbose); }); } login(accessToken, verbose = false) { return __awaiter(this, void 0, void 0, function* () { const credentialsPath = path_1.resolve(os_1.homedir(), TOKEN_FILENAME); process.stdout.write(colorette_1.gray('\n Logging in...\n')); try { yield this.verifyToken(accessToken, this.region, verbose); } catch (err) { process.stdout.write(colorette_1.red('Authorization failed. Please check if you entered a valid API key.\n')); process.exit(1); } const credentials = Object.assign(Object.assign({}, this.readCredentialsFile(credentialsPath)), { [this.region]: accessToken, token: accessToken }); this.accessTokens = credentials; this.registryApi.setAccessTokens(credentials); fs_1.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2)); process.stdout.write(colorette_1.green(' Authorization confirmed. ✅\n\n')); }); } logout() { const credentialsPath = path_1.resolve(os_1.homedir(), TOKEN_FILENAME); if (fs_1.existsSync(credentialsPath)) { fs_1.unlinkSync(credentialsPath); } process.stdout.write('Logged out from the Redocly account. ✋\n'); } } exports.RedoclyClient = RedoclyClient; function isRedoclyRegistryURL(link) { const domain = REDOCLY_DOMAIN || process.env.REDOCLY_DOMAIN || config_1.DOMAINS[config_1.DEFAULT_REGION]; const legacyDomain = domain === 'redocly.com' ? 'redoc.ly' : domain; if (!link.startsWith(`https://api.${domain}/registry/`) && !link.startsWith(`https://api.${legacyDomain}/registry/`)) { return false; } return true; } exports.isRedoclyRegistryURL = isRedoclyRegistryURL;