UNPKG

balena-cli

Version:

The official balena Command Line Interface

120 lines (106 loc) 3.44 kB
/** * @license * Copyright 2020 Balena Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { type Hook, type Command, // ux } from '@oclif/core'; import { InsufficientPrivilegesError } from '../errors'; import { checkLoggedIn, checkNotUsingOfflineMode } from '../utils/patterns'; let trackResolve: (result: Promise<any>) => void; // note: trackPromise is subject to a Bluebird.timeout, defined in events.ts export const trackPromise = new Promise((resolve) => { trackResolve = resolve; }); /** * Throw InsufficientPrivilegesError if not root on Mac/Linux * or non-Administrator on Windows. * * Called automatically if `root=true`. * Can be called explicitly by command implementation, if e.g.: * - check should only be done conditionally * - other code needs to execute before check */ const checkElevatedPrivileges = async () => { const isElevated = await (await import('is-elevated'))(); if (!isElevated) { throw new InsufficientPrivilegesError( 'You need root/admin privileges to run this command', ); } }; /** * Require elevated privileges to run. * When set to true, command will exit with an error * if executed without root on Mac/Linux * or if executed by non-Administrator on Windows. */ const DEFAULT_ROOT = false; /** * Require authentication to run. * When set to true, command will exit with an error * if user is not already logged in. */ const DEFAULT_AUTHENTICATED = false; /** * Require an internet connection to run. * When set to true, command will exit with an error * if user is running in offline mode (BALENARC_OFFLINE_MODE). */ const DEFAULT_OFFLINE_COMPATIBLE = false; /** * This is an oclif 'prerun' hook. This hook runs after the command line is * parsed by oclif, but before the command's run() function is called. * See: https://oclif.io/docs/hooks * * This hook is used to track CLI command signatures (usage analytics). * A command signature is something like "env set NAME [VALUE]". That's * literally so: 'NAME' and 'VALUE' are NOT replaced with actual values. */ const hook: Hook<'prerun'> = async function (options) { try { if ( (options.Command as Command.Class & { root: boolean }).root ?? DEFAULT_ROOT ) { await checkElevatedPrivileges(); } if ( (options.Command as Command.Class & { authenticated: boolean }) .authenticated ?? DEFAULT_AUTHENTICATED ) { await checkLoggedIn(); } if ( !( (options.Command as Command.Class & { offlineCompatible: boolean }) .offlineCompatible ?? DEFAULT_OFFLINE_COMPATIBLE ) ) { await checkNotUsingOfflineMode(); } } catch (error) { this.error(error); } const events = await import('../events'); const cmd = options.Command.id; // Intentionally do not await for the track promise here, in order to // run the command tracking and the command itself in parallel. trackResolve(events.trackCommand(cmd)); }; export default hook;