Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@heroku-cli/command

Package Overview
Dependencies
Maintainers
56
Versions
128
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@heroku-cli/command - npm Package Compare versions

Comparing version
12.0.2
to
12.1.0
+2
-0
lib/api-client.d.ts

@@ -6,2 +6,4 @@ import { HTTP, HTTPError, HTTPRequestOptions } from '@heroku/http-call';

import { ParticleboardClient } from './particleboard-client.js';
export declare const ALLOWED_HEROKU_DOMAINS: readonly string[];
export declare const LOCALHOST_DOMAINS: readonly string[];
export declare namespace APIClient {

@@ -8,0 +10,0 @@ interface Options extends HTTPRequestOptions {

@@ -14,2 +14,4 @@ import { HTTP, HTTPError } from '@heroku/http-call';

const netrc = new Netrc();
export const ALLOWED_HEROKU_DOMAINS = Object.freeze(['heroku.com', 'herokai.com', 'herokuspace.com', 'herokudev.com']);
export const LOCALHOST_DOMAINS = Object.freeze(['localhost', '127.0.0.1']);
export class HerokuAPIError extends Errors.CLIError {

@@ -118,2 +120,3 @@ body;

}
// eslint-disable-next-line complexity
static async request(url, opts = {}, retries = 3) {

@@ -136,3 +139,17 @@ opts.headers = opts.headers || {};

if (!Object.keys(opts.headers).some(h => h.toLowerCase() === 'authorization')) {
opts.headers.authorization = `Bearer ${self.auth}`;
// Handle both relative and absolute URLs for validation
let targetUrl;
try {
// Try absolute URL first
targetUrl = new URL(url);
}
catch {
// If that fails, assume it's relative and prepend the API base URL
targetUrl = new URL(url, vars.apiUrl);
}
const isHerokuApi = ALLOWED_HEROKU_DOMAINS.some(domain => targetUrl.hostname.endsWith(`.${domain}`));
const isLocalhost = LOCALHOST_DOMAINS.includes(targetUrl.hostname);
if (isHerokuApi || isLocalhost) {
opts.headers.authorization = `Bearer ${self.auth}`;
}
}

@@ -139,0 +156,0 @@ this.configDelinquency(url, opts);

@@ -12,3 +12,4 @@ export declare class Vars {

get particleboardUrl(): string;
private isValidHerokuHost;
}
export declare const vars: Vars;

@@ -0,2 +1,4 @@

import { ux } from '@oclif/core';
import * as url from 'node:url';
import { ALLOWED_HEROKU_DOMAINS, LOCALHOST_DOMAINS } from './api-client.js';
export class Vars {

@@ -37,3 +39,8 @@ get apiHost() {

get host() {
return this.envHost || 'heroku.com';
const { envHost } = this;
if (envHost && !this.isValidHerokuHost(envHost)) {
ux.warn(`Invalid HEROKU_HOST '${envHost}' - using default`);
return 'heroku.com';
}
return envHost || 'heroku.com';
}

@@ -59,3 +66,8 @@ get httpGitHost() {

}
isValidHerokuHost(host) {
// Remove protocol if present
const cleanHost = host.replace(/^https?:\/\//, '');
return ALLOWED_HEROKU_DOMAINS.some(domain => cleanHost.endsWith(`.${domain}`)) || LOCALHOST_DOMAINS.some(domain => cleanHost.includes(domain));
}
}
export const vars = new Vars();
+1
-1
{
"name": "@heroku-cli/command",
"description": "base class for Heroku CLI commands",
"version": "12.0.2",
"version": "12.1.0",
"author": "Heroku",

@@ -6,0 +6,0 @@ "bugs": "https://github.com/heroku/heroku-cli-command/issues",