Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 3 additions & 30 deletions docker/openemr/flex/openemr.sh
Original file line number Diff line number Diff line change
Expand Up @@ -593,38 +593,11 @@ if [[ "${NEED_COMPOSER_BUILD}" = "true" ]] || [[ "${NEED_NPM_BUILD}" = "true" ]]
return 1
}

token_configured=false

# if there is a raw github composer token supplied, then try to use it
# if there is a github composer token supplied, then try to use it
if [[ -n ${GITHUB_COMPOSER_TOKEN} ]]; then
echo 'trying raw github composer token'
# shellcheck disable=SC2310
if try_github_token "${GITHUB_COMPOSER_TOKEN}" 'raw github composer token'; then
token_configured=true
fi
fi

# if there is no raw github composer token supplied or it was invalid, try a base64 encoded one (if it was supplied)
if [[ ${token_configured} != true && -n ${GITHUB_COMPOSER_TOKEN_ENCODED} ]]; then
echo 'trying encoded github composer token'
decoded_token=$(base64 -d <<< "${GITHUB_COMPOSER_TOKEN_ENCODED}")
echo 'trying github composer token'
# shellcheck disable=SC2310
if try_github_token "${decoded_token}" 'encoded github composer token'; then
token_configured=true
fi
fi

# if there is no raw github composer token and/or base64 encoded one supplied or they were invalid, then try a character code encoded one (if it was supplied)
if [[ ${token_configured} != true && -n ${GITHUB_COMPOSER_TOKEN_ENCODED_ALTERNATE} ]]; then
echo 'trying alternate encoded github composer token'
# Word splitting is intentional here to convert space-separated string to array
# shellcheck disable=SC2206
codes=(${GITHUB_COMPOSER_TOKEN_ENCODED_ALTERNATE})
decoded_token=$(printf '%b' "$(printf '\\%03o' "${codes[@]}")")
# shellcheck disable=SC2310
if try_github_token "${decoded_token}" 'alternate encoded github composer token'; then
token_configured=true
fi
try_github_token "${GITHUB_COMPOSER_TOKEN}" 'github composer token' || true
fi

# install php dependencies
Expand Down
103 changes: 101 additions & 2 deletions utilities/openemr-cmd/openemr-cmd
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ set -euo pipefail
#################################################################################################

# Increment the version when modify script
VERSION="1.0.25"
VERSION="1.0.26"
# If the docker is snap or non-snap docker
# Setting the container names accordingly
get_container_names() {
Expand Down Expand Up @@ -366,6 +366,89 @@ docker-pull-image(){
done <<< "${services}"
}

# Walk the developer through creating/updating the .env file for the easydev
# docker-compose environment, so that secrets like GITHUB_COMPOSER_TOKEN are
# never committed to the repository in plaintext.
setup_composer_env() {
local ENV_FILE

if [[ ! -f "docker-compose.yml" ]]; then
echo "Error: docker-compose.yml not found in current directory." >&2
echo "Please run this command from the docker/development-easy directory." >&2

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't this also be other directories? (insane one, predis one)

exit 1
fi

ENV_FILE="../../.env"

echo ""
echo "=== OpenEMR Easydev Composer Token Setup ==="
echo ""
echo "A GitHub Personal Access Token lets Composer avoid GitHub API rate limits"
echo "when pulling dependencies. It should never be committed to the repository."
echo "This writes GITHUB_COMPOSER_TOKEN plus its derived encoded variants to: ${ENV_FILE}"

Copilot AI Apr 2, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setup text says it will write “derived encoded variants” of the token, but this function only writes GITHUB_COMPOSER_TOKEN. Either remove that wording or actually write the encoded variants (if they’re still needed elsewhere).

Suggested change
echo "This writes GITHUB_COMPOSER_TOKEN plus its derived encoded variants to: ${ENV_FILE}"
echo "This writes GITHUB_COMPOSER_TOKEN to: ${ENV_FILE}"

Copilot uses AI. Check for mistakes.
echo ""

# Show current state if .env already exists
if [[ -f "${ENV_FILE}" ]]; then
local existing_token
existing_token=$(grep "^GITHUB_COMPOSER_TOKEN=" "${ENV_FILE}" | cut -d= -f2 || true)
if [[ -n "${existing_token}" ]]; then
echo "Current token in .env: ${existing_token:0:12}... (truncated for display)"
else
echo "Found existing .env but no GITHUB_COMPOSER_TOKEN entry."
fi
local RESP
read -r -e -p "Update it? [y/N] " RESP </dev/tty
if [[ -z "${RESP}" || "${RESP,,}" != "y" ]]; then
echo "No changes made."
return
fi
echo ""
fi

echo "Generate a token at: https://github.com/settings/tokens"
echo "No special scopes are required for public repos."
echo ""

local TOKEN
read -r -e -p "Paste your GitHub Personal Access Token: " TOKEN </dev/tty

Copilot AI Apr 2, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prompt reads the PAT with normal read, which echoes the token to the terminal and stores it in scrollback/history for many shells. Use silent input (eg, read -s) and consider disabling readline (-e) for secret entry.

Suggested change
read -r -e -p "Paste your GitHub Personal Access Token: " TOKEN </dev/tty
read -r -s -p "Paste your GitHub Personal Access Token: " TOKEN </dev/tty
echo ""

Copilot uses AI. Check for mistakes.

if [[ -z "${TOKEN}" ]]; then
echo "Error: No token provided. Aborting." >&2
exit 1
fi

if [[ "${TOKEN}" != ghp_* && "${TOKEN}" != github_pat_* ]]; then
echo ""
echo "Warning: Token does not look like a standard GitHub PAT"
echo " (expected ghp_... or github_pat_... prefix)."
local RESP
read -r -e -p "Continue anyway? [y/N] " RESP </dev/tty
if [[ -z "${RESP}" || "${RESP,,}" != "y" ]]; then
echo "Aborting."
exit 1
fi
fi

# Write token to .env (overwrite if already present)
{
grep -v "^GITHUB_COMPOSER_TOKEN=" "${ENV_FILE}" 2>/dev/null || true
} > "${ENV_FILE}.tmp"
cat >> "${ENV_FILE}.tmp" << EOF
# OpenEMR easydev environment variables
# DO NOT COMMIT THIS FILE — contains sensitive credentials
GITHUB_COMPOSER_TOKEN=${TOKEN}
EOF
mv "${ENV_FILE}.tmp" "${ENV_FILE}"

echo ""
echo "✓ Written to ${ENV_FILE}: GITHUB_COMPOSER_TOKEN = ${TOKEN:0:12}..."
echo " (.env is covered by the root .gitignore)"

Copilot AI Apr 2, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This message claims the root .gitignore covers .env, but the repo’s .gitignore currently does not ignore .env. Since this command creates/updates ../../.env with a PAT, this is a real risk of accidentally committing credentials. Either update the repo ignore rules / use a file that’s already ignored, or change the guidance and default path.

Suggested change
echo " (.env is covered by the root .gitignore)"
echo " WARNING: ${ENV_FILE} is not ignored by git by default. Add it to .gitignore to avoid committing credentials."

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added .env to the .gitignore here in this repo even though it applies when running in openemr

echo ""
echo "Run: openemr-cmd up"
echo ""
}

USAGE_EXIT_CODE=13
VERSION_EXIT_CODE=14
FINAL_EXIT_CODE=0
Expand Down Expand Up @@ -481,6 +564,7 @@ if [[ $# -eq 0 || "${FIRST_ARG}" = '--help' || "${FIRST_ARG}" = '-h' ]]; then
echo " el, enable-ldap Turn on support for LDAP - login credentials are admin:admin"
echo " dld, disable-ldap Turn off support for LDAP - standard login credentials"
echo " ec, encoding-collation Change the database character set and collation"
echo " sce, setup-composer-env Create/update .env with GITHUB_COMPOSER_TOKEN (keeps secrets out of git)"

exit "${USAGE_EXIT_CODE}"

Expand Down Expand Up @@ -532,7 +616,7 @@ MARIADB_CONTAINER_ID="${mariadb_id:-}" # Set to empty if not found
# Check if a target container ID was determined or provided before proceeding with commands that need it
# (Allow proceeding if the command doesn't require a container, like up, down, start, stop, --help, --version)
case "${FIRST_ARG}" in
up|down|start|stop|--help|-h|--version|-v)
up|down|start|stop|--help|-h|--version|-v|sce|setup-composer-env)
# These commands don't necessarily need a running container ID determined here
;;
*)
Expand All @@ -551,6 +635,18 @@ esac
# For the shift usage, it used to cover the insane env.
case "${FIRST_ARG}" in
up)
if [[ ! -f "../../.env" ]] || ! grep -q "^GITHUB_COMPOSER_TOKEN=." "../../.env" 2>/dev/null; then
echo "No GITHUB_COMPOSER_TOKEN found in ../../.env — running setup first."
setup_composer_env
else
UP_TOKEN=$(grep "^GITHUB_COMPOSER_TOKEN=" "../../.env" | cut -d= -f2)
UP_REMAINING=$(curl -sf -H "Authorization: token ${UP_TOKEN}" \
https://api.github.com/rate_limit | grep -o '"remaining":[0-9]*' | head -1 | cut -d: -f2)

Copilot AI Apr 2, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With set -euo pipefail, this command substitution will cause openemr-cmd up to exit immediately if curl fails (offline), GitHub is unreachable, or grep finds no match. Wrap the curl/parse pipeline in || true (or temporarily disable errexit) and handle an empty/failed response explicitly so up still proceeds or falls back to setup_composer_env. Also note the PAT is passed on the curl command line (visible via process listings); consider avoiding this validity check or using a safer mechanism.

Suggested change
https://api.github.com/rate_limit | grep -o '"remaining":[0-9]*' | head -1 | cut -d: -f2)
https://api.github.com/rate_limit | grep -o '"remaining":[0-9]*' | head -1 | cut -d: -f2 || true)

Copilot uses AI. Check for mistakes.
if [[ -z "${UP_REMAINING}" || "${UP_REMAINING}" -lt 100 ]]; then
echo "GITHUB_COMPOSER_TOKEN is expired, revoked, or rate-limited — running setup."
setup_composer_env
fi
fi
run_docker_compose up -d
;;
down)
Expand Down Expand Up @@ -623,6 +719,9 @@ case "${FIRST_ARG}" in
ms|maria-shell)
quick_open_a_maria_docker_shell
;;
sce|setup-composer-env)
setup_composer_env
;;
bt)
run_devtools_in_docker "${CONTAINER_ID}" build-themes
;;
Expand Down
Loading