Add way for infisical to switch accounts when signed into wrong account
This commit is contained in:
Executable
+177
@@ -0,0 +1,177 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
LOCAL_FILE="${SPOON_INFISICAL_LOCAL_FILE:-$ROOT_DIR/.local/infisical.env}"
|
||||
INFISICAL_DIR="${HOME}/.infisical"
|
||||
CONFIG_FILE="$INFISICAL_DIR/infisical-config.json"
|
||||
LOCK_FILE="$INFISICAL_DIR/.switch.lock"
|
||||
|
||||
usage() {
|
||||
printf 'usage: infisical-account <ensure|status>\n' >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
require_command() {
|
||||
local command_name="$1"
|
||||
if ! command -v "$command_name" >/dev/null 2>&1; then
|
||||
printf 'infisical-account: required command not found: %s\n' "$command_name" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
require_dependencies() {
|
||||
require_command infisical
|
||||
require_command jq
|
||||
require_command flock
|
||||
}
|
||||
|
||||
require_config() {
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
printf 'infisical-account: Infisical config not found at ~/.infisical/infisical-config.json.\n' >&2
|
||||
printf 'Run: infisical login\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
logged_in_user_count() {
|
||||
jq -er '
|
||||
if (.loggedInUsers | type) == "array" then
|
||||
.loggedInUsers | length
|
||||
else
|
||||
error("loggedInUsers missing")
|
||||
end
|
||||
' "$CONFIG_FILE" 2>/dev/null || {
|
||||
printf 'infisical-account: Infisical config is invalid or missing loggedInUsers.\n' >&2
|
||||
printf 'Run: infisical login\n' >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
print_logged_in_accounts() {
|
||||
jq -r '(.loggedInUsers // [])[] | " - \(.email)"' "$CONFIG_FILE"
|
||||
}
|
||||
|
||||
trim() {
|
||||
local value="$1"
|
||||
value="${value#"${value%%[![:space:]]*}"}"
|
||||
value="${value%"${value##*[![:space:]]}"}"
|
||||
printf '%s' "$value"
|
||||
}
|
||||
|
||||
strip_matching_quotes() {
|
||||
local value="$1"
|
||||
case "$value" in
|
||||
\"*\") value="${value#\"}"; value="${value%\"}" ;;
|
||||
\'*\') value="${value#\'}"; value="${value%\'}" ;;
|
||||
esac
|
||||
printf '%s' "$value"
|
||||
}
|
||||
|
||||
read_project_email() {
|
||||
if [[ ! -f "$LOCAL_FILE" ]]; then
|
||||
printf 'infisical-account: multiple Infisical users are logged in, but .local/infisical.env is missing.\n\n' >&2
|
||||
printf 'Create it with:\n' >&2
|
||||
printf ' mkdir -p .local\n' >&2
|
||||
printf ' printf "INFISICAL_EMAIL=you@example.com\\n" > .local/infisical.env\n\n' >&2
|
||||
printf 'Logged-in accounts:\n' >&2
|
||||
print_logged_in_accounts >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local email=""
|
||||
local line key value
|
||||
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||
line="$(trim "$line")"
|
||||
case "$line" in
|
||||
''|'#'*) continue ;;
|
||||
esac
|
||||
key="$(trim "${line%%=*}")"
|
||||
value="${line#*=}"
|
||||
if [[ "$key" == "$line" ]]; then
|
||||
continue
|
||||
fi
|
||||
value="$(strip_matching_quotes "$(trim "$value")")"
|
||||
if [[ "$key" == "INFISICAL_EMAIL" ]]; then
|
||||
email="$value"
|
||||
break
|
||||
fi
|
||||
done < "$LOCAL_FILE"
|
||||
|
||||
if [[ -z "$email" ]]; then
|
||||
printf 'infisical-account: .local/infisical.env must contain INFISICAL_EMAIL=you@example.com.\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf '%s' "$email"
|
||||
}
|
||||
|
||||
domain_for_email() {
|
||||
local email="$1"
|
||||
jq -er --arg email "$email" '
|
||||
first((.loggedInUsers // [])[] | select(.email == $email) | .domain)
|
||||
' "$CONFIG_FILE"
|
||||
}
|
||||
|
||||
switch_to_email() {
|
||||
local email="$1"
|
||||
local domain
|
||||
domain="$(domain_for_email "$email")" || {
|
||||
printf 'infisical-account: configured Infisical user is not logged in locally: %s\n' "$email" >&2
|
||||
printf 'Run: infisical login\n' >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
local tmp
|
||||
tmp="$(mktemp "$INFISICAL_DIR/infisical-config.XXXXXX")"
|
||||
jq --arg email "$email" --arg domain "$domain" '
|
||||
.loggedInUserEmail = $email
|
||||
| .LoggedInUserDomain = $domain
|
||||
' "$CONFIG_FILE" > "$tmp"
|
||||
chmod 600 "$tmp"
|
||||
mv "$tmp" "$CONFIG_FILE"
|
||||
}
|
||||
|
||||
ensure_account() {
|
||||
require_dependencies
|
||||
require_config
|
||||
|
||||
(
|
||||
flock 9
|
||||
local count
|
||||
count="$(logged_in_user_count)"
|
||||
if [[ "$count" -eq 0 ]]; then
|
||||
printf 'infisical-account: no local Infisical users are logged in.\n' >&2
|
||||
printf 'Run: infisical login\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$count" -eq 1 ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
local email
|
||||
email="$(read_project_email)"
|
||||
switch_to_email "$email"
|
||||
) 9>"$LOCK_FILE"
|
||||
}
|
||||
|
||||
status() {
|
||||
ensure_account
|
||||
local count configured active
|
||||
count="$(logged_in_user_count)"
|
||||
configured="not required"
|
||||
if [[ -f "$LOCAL_FILE" ]]; then
|
||||
configured="$(read_project_email 2>/dev/null || printf 'invalid')"
|
||||
fi
|
||||
active="$(jq -r '.loggedInUserEmail // "unknown"' "$CONFIG_FILE")"
|
||||
|
||||
printf 'Infisical accounts logged in: %s\n' "$count"
|
||||
printf 'Configured project email: %s\n' "$configured"
|
||||
printf 'Active account after ensure: %s\n' "$active"
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
ensure) ensure_account ;;
|
||||
status) status ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
Reference in New Issue
Block a user