New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@pinpt/cli

Package Overview
Dependencies
Maintainers
4
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@pinpt/cli - npm Package Compare versions

Comparing version
0.0.9
to
1.0.0
+4
-1
bin/cli.mjs

@@ -19,3 +19,3 @@ #!/usr/bin/env node

logout: { description: 'Logout of Pinpoint on this machine' },
signup: { description: 'Signup for Pinpoint' },
// signup: { description: 'Signup for Pinpoint' },
};

@@ -26,2 +26,5 @@

const [options, args] = getArgs(optionSpec);
if (args.length === 0 || !commandSpec[args[0]]) {
options.help = true;
}
await run({ args, options, optionSpec, commandSpec, meta: import.meta });

@@ -28,0 +31,0 @@ } catch (ex) {

+1
-0

@@ -121,2 +121,3 @@ import prompts from 'prompts';

body,
apiKeyRequired: true,
onProgress: (progress) => {

@@ -123,0 +124,0 @@ if (p) {

import { getSignup } from './signup.mjs';
import { saveAPIKey } from './util.mjs';
export const login = async ({ args }) => {
export const login = async ({ args, options }) => {
if (args && args[0] === 'login') {
saveAPIKey(); // remove it
await getSignup('login');
await getSignup('login', options.host);
}
};

@@ -5,3 +5,3 @@ import prompts from 'prompts';

import terminalLink from 'terminal-link';
import { getAPIKey, saveConfigProps, saveAPIKey, apiRequest, debug, error, tick, configFileName } from './util.mjs';
import { getAPIKey, saveAPIKey, apiRequest, error, tick, configFileName, selectUser } from './util.mjs';

@@ -28,3 +28,3 @@ const getEmailPrompt = () => {

const handlePromptFlow = async (email, loginToken, userId) => {
const handlePromptFlow = async (email, loginToken, userId, apihost) => {
console.log();

@@ -35,2 +35,3 @@ console.log(

console.log();
let siteIds;
while (true) {

@@ -51,3 +52,3 @@ const code = await prompts(

try {
await apiRequest('Verifying the code', '/user/signup/code', {
const res = await apiRequest('Verifying the code', '/user/signup/code', {
body: { email: email, code: code.value },

@@ -57,2 +58,3 @@ method: 'PUT',

});
siteIds = res.siteIds;
break;

@@ -78,4 +80,3 @@ } catch (ex) {

// save it
saveAPIKey(loginToken, Date.now() + 2.592e9 - 40000);
saveConfigProps({ userId });
saveAPIKey(apihost, userId, loginToken, Date.now() + 2.592e9 - 40000, siteIds, email);
tick(`We saved your cached credentials at ${configFileName}`);

@@ -110,4 +111,7 @@ console.log();

export const selectSite = async () => {
const { sites } = await apiRequest('Fetching your sites', '/user/sites');
export const selectSite = async (apihost) => {
const userId = await selectUser(apihost);
const apiKey = getAPIKey(apihost, '', userId);
const { sites } = await apiRequest('Fetching your sites', '/user/sites', { apiKey, apiKeyRequired: true });
if (sites.length === 0) {

@@ -141,15 +145,3 @@ error('No sites found. Please create a site first.', true);

export const getSignup = async (action) => {
const apikey = getAPIKey();
if (apikey) {
try {
await apiRequest('Verifying your credentials', '/auth/ping', { quiet: true, failOnError: false });
debug('we already have a valid and unexpired apikey');
return; // succeeded
} catch (ex) {
saveAPIKey(); // delete it
// ignore if failed, as that means it's not authorized, invalid, etc
}
}
export const getSignup = async (action, apihost) => {
let signup = action === 'signup';

@@ -185,3 +177,3 @@ let login = action === 'login';

const { userId, loginToken } = res;
await handlePromptFlow(email.value, loginToken, userId);
await handlePromptFlow(email.value, loginToken, userId, apihost);
} else {

@@ -364,3 +356,3 @@ const signup = { user: {}, site: {}, offline: true };

const { userId, loginToken } = res;
await handlePromptFlow(signup.user.email, loginToken, userId);
await handlePromptFlow(signup.user.email, loginToken, userId, apihost);
console.log();

@@ -372,6 +364,6 @@ console.log(c.bold(c.green('🚀 Your account is activated!')));

export const signup = async ({ args }) => {
export const signup = async ({ args, options }) => {
if (args && args[0] === 'signup') {
await getSignup('signup');
await getSignup('signup', options.host);
}
};

@@ -9,2 +9,3 @@ import CFonts from 'cfonts';

import vm from 'vm';
import prompts from 'prompts';
import terminalLink from 'terminal-link';

@@ -97,2 +98,17 @@ import getstream from 'get-stream';

/**
* structure for config:
*
* "apihost": {
* "userId": {
* "siteIds": [],
* "apikey": {
* "value": "",
* "expires": ""
* }
* }
* }
*
*/
export const getConfig = () => {

@@ -110,9 +126,28 @@ if (CONFIG) {

export const saveAPIKey = (value, expires) => {
export const saveAPIKey = (apihost, userId, value, expires, siteIds, email) => {
if (!apihost) {
if (fs.existsSync(configFileName)) {
fs.unlinkSync(configFileName);
}
return;
}
const c = getConfig() || {};
const _apiconfig = c[apihost] || {};
if (value && expires > Date.now()) {
c.apikey = { value, expires };
_apiconfig[userId] = {
email,
siteIds,
apikey: {
value,
expires,
},
};
} else {
delete c.apikey; // delete it
if (userId) {
delete _apiconfig[userId];
} else {
delete c[apihost];
}
}
c[apihost] = _apiconfig;
CONFIG = c;

@@ -123,15 +158,31 @@ fs.writeFileSync(configFileName, JSON.stringify(c, null, 2));

export const getConfigProp = (key) => {
const c = getConfig() || {};
return c[key];
export const selectUser = async (apihost) => {
const config = getConfig();
if (config) {
const _apiconfig = config[apihost];
if (_apiconfig) {
const userIds = Object.keys(_apiconfig);
if (userIds === 1) {
return userIds[0];
}
const user = await prompts(
{
type: 'select',
name: 'value',
message: 'Please pick the user you want to use:',
choices: userIds.map((userId) => ({ title: _apiconfig[userId].email, description: userId })),
},
{
onCancel: () => {
process.exit(0);
},
}
);
return userIds[user.value];
}
}
error('Your login session has expired or you need to login for the first time', true);
};
export const saveConfigProps = (props) => {
const c = { ...(getConfig() || {}), ...props };
CONFIG = c;
fs.writeFileSync(configFileName, JSON.stringify(c, null, 2));
fs.chmodSync(configFileName, '600');
};
export const getAPIKey = () => {
export const getAPIKey = (apihost, siteId, _userId) => {
if (process.env.PINPOINT_API_KEY) {

@@ -141,11 +192,21 @@ return process.env.PINPOINT_API_KEY;

const config = getConfig();
if (config && config.apikey) {
const { value, expires } = config.apikey;
const expired = expires <= Date.now();
if (!expired) {
// if it expires in the future, return it
return value;
if (config) {
const _configForHost = config[apihost];
if (_configForHost) {
const userId =
_userId ||
Object.keys(_configForHost).find(
(userId) => _configForHost[userId].siteIds && _configForHost[userId].siteIds.includes(siteId)
);
if (userId) {
const { value, expires = 0 } = _configForHost[userId].apikey || {};
const expired = expires <= Date.now();
if (!expired) {
// if it expires in the future, return it
return value;
}
debug('need to remove expired api key');
saveAPIKey(apihost, userId); // remove it since expired
}
}
debug('need to remove expired api key');
saveAPIKey(); // remove it since expired
}

@@ -186,2 +247,4 @@ return null;

const sleep = (timeout) => new Promise((resolve) => setTimeout(resolve, timeout));
export const apiRequest = async (help, basepath, params = {}) => {

@@ -193,2 +256,3 @@ const {

failOnError = true,
apiKeyRequired = false,
apiKey,

@@ -203,4 +267,15 @@ checkSuccess,

}
const { apihost } = readPinpointConfig();
const _apiKey = apiKey || getAPIKey();
let _apiKey = apiKey;
let apihost = _options.host;
if (apiKeyRequired && !_apiKey) {
const { apihost: _apihost, siteId } = readPinpointConfig();
_apiKey = getAPIKey(apihost, siteId);
if (!_apiKey) {
error(
'You are not logged in to this site or your login session has expired. Please login again and try again.',
true
);
}
apihost = _apihost;
}
const headers = {};

@@ -213,3 +288,3 @@ const [ip, machine] = await Promise.all([ipAddress(), getSystemInfo()]);

headers['x-pinpoint-machine'] = machine;
const url = `https://${apihost || _options.host}${basepath}`;
const url = `https://${apihost}${basepath}`;
const _method = body ? method : 'GET';

@@ -246,10 +321,19 @@ const isStream = body instanceof FormData;

} else {
g = got(url, {
headers,
method: _method,
responseType: 'json',
body: _body,
throwHttpErrors: false,
});
p = g;
let count = 0;
while (true) {
count++;
g = got(url, {
headers,
method: _method,
responseType: 'json',
body: _body,
throwHttpErrors: false,
});
p = await g;
if (p.statusCode === 502) {
await sleep(count * Math.max(150, Math.random() * 500)); // exponential backoff
continue;
}
break;
}
}

@@ -256,0 +340,0 @@ const res = await p;

{
"name": "@pinpt/cli",
"version": "0.0.9",
"version": "1.0.0",
"description": "Pinpoint CLI",

@@ -5,0 +5,0 @@ "bin": {