@sentry/wizard
Version:
Sentry wizard helping you to configure your project
164 lines • 6.31 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PromptForParameters = void 0;
const inquirer_1 = require("inquirer");
const Logging_1 = require("../Helper/Logging");
const Wizard_1 = require("../Helper/Wizard");
const BaseStep_1 = require("./BaseStep");
class PromptForParameters extends BaseStep_1.BaseStep {
async emit(answers) {
this.debug(answers);
if (!(await (0, Wizard_1.getCurrentIntegration)(answers).shouldEmit(answers))) {
return {};
}
if (this._argv.quiet) {
return {};
}
let url = this._getFullUrl(answers);
const organization = await (0, inquirer_1.prompt)([
{
message: 'Organization Slug:',
name: 'slug',
type: 'input',
// eslint-disable-next-line @typescript-eslint/unbound-method
validate: this._validateSlug,
when: this._shouldAsk(answers, 'config.organization.slug', () => {
(0, Logging_1.dim)('Please copy/paste your organization slug');
(0, Logging_1.dim)(`It can be found in the url ${url}`);
}),
},
]);
url = this._getFullUrl(answers, organization.slug);
const project = await (0, inquirer_1.prompt)([
{
message: 'Project Slug:',
name: 'slug',
type: 'input',
// eslint-disable-next-line @typescript-eslint/unbound-method
validate: this._validateSlug,
when: this._shouldAsk(answers, 'config.project.slug', () => {
(0, Logging_1.dim)('Please copy/paste your project slug');
(0, Logging_1.dim)(`It can be found in the url ${url}`);
}),
},
]);
url = this._getFullUrl(answers, organization.slug, project.slug);
const dsnKeyUrl = this._getDSNKeyUrl(answers, project.slug);
const dsn = await (0, inquirer_1.prompt)([
{
message: 'DSN:',
name: 'public',
type: 'input',
// eslint-disable-next-line @typescript-eslint/unbound-method
validate: this._validateDSN,
when: this._shouldAsk(answers, 'config.dsn.public', () => {
(0, Logging_1.dim)('Please copy/paste your DSN');
(0, Logging_1.dim)(`It can be found here: ${dsnKeyUrl}`);
}),
},
]);
const auth = await (0, inquirer_1.prompt)([
{
message: 'Auth Token:',
name: 'token',
type: 'input',
// eslint-disable-next-line @typescript-eslint/unbound-method
validate: this._validateAuthToken,
when: this._shouldAsk(answers, 'config.auth.token', () => {
(0, Logging_1.dim)('Please copy/paste your auth token');
(0, Logging_1.dim)(`It can be found here: ${this._argv.url}api/`);
(0, Logging_1.dim)('In case there is none yet, create one with [project:releases] permission');
}),
},
]);
return {
config: {
...answers.config,
auth,
dsn,
project,
organization,
},
};
}
_getFullUrl(answers, organizationSlug, projectSlug) {
const baseUrl = this._argv.url;
const orgSlug = answers.config?.organization?.slug ??
organizationSlug ??
'organization_slug';
const projSlug = answers.config?.project?.slug ?? projectSlug ?? 'project_slug';
return `${baseUrl}${orgSlug}/${projSlug}`;
}
_getDSNKeyUrl(answers, projectSlug) {
const baseUrl = this._argv.url;
const projSlug = answers.config?.project?.slug ?? projectSlug ?? 'project_slug';
return `${baseUrl}settings/projects/${projSlug}/keys`;
}
_shouldAsk(answers, configKey, preHook) {
const shouldAsk = answers[configKey] != null;
if (shouldAsk && preHook) {
preHook();
}
return shouldAsk;
}
_validateAuthToken(input) {
const isOrgToken = input.startsWith('sntrys_');
if (isOrgToken) {
if (!isValidOrgToken(input)) {
return 'Make sure you correctly copied your auth token. It should start with "sntrys_"';
}
return true;
}
if (!input.match(/(sntrys_)?[0-9a-f]{64}/g)) {
return 'Make sure you copied the correct auth token, it should be 64 hex chars';
}
return true;
}
_validateSlug(input) {
if (input.match(/[A-Z]/g)) {
return 'Please copy the slug from the url, it should be all lowercase';
}
if (input.length === 0) {
return "Can't be empty";
}
return true;
}
_validateDSN(input) {
const match = input.match(/^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w.-]+)(?::(\d+))?(\/.*)$/);
if (!match) {
return 'Invalid DSN format';
}
if (match[1] !== 'http' && match[1] !== 'https') {
return `Unsupported protocol for DSN: ${match[1]}`;
}
return true;
}
}
exports.PromptForParameters = PromptForParameters;
/**
* Trying to parse and decode an org auth token. Based on:
* - https://github.com/getsentry/rfcs/blob/main/text/0091-ci-upload-tokens.md#parsing-tokens
* - https://github.com/getsentry/rfcs/blob/main/text/0091-ci-upload-tokens.md#token-facts
*/
function isValidOrgToken(input) {
if (!input.startsWith('sntrys_')) {
return false;
}
const tokenParts = input.split('_');
if (tokenParts.length < 3) {
return false;
}
try {
const payload = tokenParts[1];
const decodedPayload = Buffer.from(payload, 'base64').toString();
const jsonPayload = JSON.parse(decodedPayload);
if (!jsonPayload.iat || !jsonPayload.url || !jsonPayload.org) {
return false;
}
}
catch {
return false;
}
return true;
}
//# sourceMappingURL=PromptForParameters.js.map