chore: harden registry auth with diagnostics and multi-domain fallback
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 41s
Build & Deploy / 🧪 QA (push) Failing after 1m26s
Build & Deploy / 🏗️ Build (push) Has been skipped
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 1s
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 41s
Build & Deploy / 🧪 QA (push) Failing after 1m26s
Build & Deploy / 🏗️ Build (push) Has been skipped
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 1s
This commit is contained in:
@@ -1,107 +1,104 @@
|
||||
#!/bin/bash
|
||||
# Hardened Registry Authentication Discovery & Hardening
|
||||
# Standard: mmintel/klz-2026
|
||||
|
||||
set -e
|
||||
|
||||
REGISTRY_DOMAIN="git.infra.mintel.me"
|
||||
REGISTRY_PATH="/api/packages/mmintel/npm/"
|
||||
# --- CONFIGURATION ---
|
||||
# The registry domain and base path for @mintel packages
|
||||
DOMAINS=("git.infra.mintel.me" "registry.infra.mintel.me")
|
||||
REGISTRY_PATH="/api/packages/mmintel/npm"
|
||||
# Package used for functional connectivity test (URL encoded)
|
||||
TEST_PACKAGE_ENCODED="%40mintel%2Fmail"
|
||||
TEST_URL="https://${REGISTRY_DOMAIN}${REGISTRY_PATH}${TEST_PACKAGE_ENCODED}"
|
||||
|
||||
echo "🔍 Starting robust functional registry discovery..."
|
||||
echo "🚀 Starting Hardened Registry Authentication Discovery..."
|
||||
|
||||
# Collect candidate tokens from environment
|
||||
# We try them all because NPM_TOKEN might be stale while GITEA_PAT is fresh
|
||||
CANDIDATES=""
|
||||
[ -n "$NPM_TOKEN" ] && CANDIDATES="${CANDIDATES} NPM_TOKEN"
|
||||
[ -n "$GITEA_PAT" ] && CANDIDATES="${CANDIDATES} GITEA_PAT"
|
||||
[ -n "$MINTEL_PRIVATE_TOKEN" ] && CANDIDATES="${CANDIDATES} MINTEL_PRIVATE_TOKEN"
|
||||
# --- TOKEN DISCOVERY ---
|
||||
# We try various candidate secrets. Gitea environment might have different names.
|
||||
CANDIDATES=(
|
||||
"NPM_TOKEN"
|
||||
"GITEA_PAT"
|
||||
"MINTEL_PRIVATE_TOKEN"
|
||||
"MINTEL_REGISTRY_TOKEN"
|
||||
"GITHUB_TOKEN"
|
||||
"GITEA_TOKEN"
|
||||
)
|
||||
|
||||
if [ -z "$CANDIDATES" ]; then
|
||||
echo "❌ No registry tokens found in environment (NPM_TOKEN, GITEA_PAT, MINTEL_PRIVATE_TOKEN are empty)."
|
||||
exit 1
|
||||
WORKING_TOKEN=""
|
||||
WORKING_DOMAIN=""
|
||||
|
||||
for DOMAIN in "${DOMAINS[@]}"; do
|
||||
echo "🔍 Testing connectivity to ${DOMAIN}..."
|
||||
|
||||
for VAR_NAME in "${CANDIDATES[@]}"; do
|
||||
TOKEN_VAL="${!VAR_NAME}"
|
||||
[ -z "${TOKEN_VAL}" ] && continue
|
||||
|
||||
echo " Testing ${VAR_NAME} (len: ${#TOKEN_VAL})..."
|
||||
|
||||
# Method 1: Bearer
|
||||
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer ${TOKEN_VAL}" "https://${DOMAIN}${REGISTRY_PATH}/${TEST_PACKAGE_ENCODED}" || echo "000")
|
||||
if [ "$STATUS" == "200" ]; then
|
||||
echo " ✅ ${VAR_NAME} verified via Bearer on ${DOMAIN}"
|
||||
WORKING_TOKEN="${TOKEN_VAL}"
|
||||
WORKING_DOMAIN="${DOMAIN}"
|
||||
break 2
|
||||
fi
|
||||
|
||||
# Method 2: Basic (Token as user, empty password)
|
||||
AUTH_BASIC=$(echo -n "${TOKEN_VAL}:" | base64)
|
||||
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Basic ${AUTH_BASIC}" "https://${DOMAIN}${REGISTRY_PATH}/${TEST_PACKAGE_ENCODED}" || echo "000")
|
||||
if [ "$STATUS" == "200" ]; then
|
||||
echo " ✅ ${VAR_NAME} verified via Basic on ${DOMAIN}"
|
||||
WORKING_TOKEN="${TOKEN_VAL}"
|
||||
WORKING_DOMAIN="${DOMAIN}"
|
||||
break 2
|
||||
fi
|
||||
|
||||
# Method 3: Basic (User 'token', Token as password - Gitea standard)
|
||||
AUTH_GITEA=$(echo -n "token:${TOKEN_VAL}" | base64)
|
||||
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Basic ${AUTH_GITEA}" "https://${DOMAIN}${REGISTRY_PATH}/${TEST_PACKAGE_ENCODED}" || echo "000")
|
||||
if [ "$STATUS" == "200" ]; then
|
||||
echo " ✅ ${VAR_NAME} verified via Gitea-Token-Basic on ${DOMAIN}"
|
||||
WORKING_TOKEN="${TOKEN_VAL}"
|
||||
WORKING_DOMAIN="${DOMAIN}"
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
if [ -z "${WORKING_TOKEN}" ]; then
|
||||
echo "⚠️ ALL functional tests failed for all domains."
|
||||
if [ -n "${NPM_TOKEN}" ]; then
|
||||
echo "Falling back to NPM_TOKEN (unverified) and git.infra.mintel.me"
|
||||
WORKING_TOKEN="${NPM_TOKEN}"
|
||||
WORKING_DOMAIN="git.infra.mintel.me"
|
||||
else
|
||||
echo "❌ CRITICAL: No usable token found and NPM_TOKEN is empty."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
AUTH_TYPE="None"
|
||||
WORKING_TOKEN=""
|
||||
# --- .npmrc GENERATION ---
|
||||
# We generate a .npmrc that matches the local pattern exactly to avoid resolution drift.
|
||||
# Local pattern:
|
||||
# @mintel:registry=https://git.infra.mintel.me/api/packages/mmintel/npm
|
||||
# //git.infra.mintel.me/api/packages/mmintel/npm/:_authToken=${TOKEN}
|
||||
|
||||
# Function to test connectivity
|
||||
check_url() {
|
||||
local label=$1
|
||||
local auth_header=$2
|
||||
local url=$3
|
||||
|
||||
# Using -k for internal cert resilience
|
||||
local code=$(curl -s -k -o /tmp/reg_body -w "%{http_code}" -H "$auth_header" "$url")
|
||||
if [ "$code" = "200" ]; then
|
||||
return 0
|
||||
else
|
||||
local body=$(cat /tmp/reg_body | head -c 100)
|
||||
echo " $label failed ($code): $body"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
cat > .npmrc << EOF
|
||||
@mintel:registry=https://${WORKING_DOMAIN}${REGISTRY_PATH}
|
||||
//${WORKING_DOMAIN}${REGISTRY_PATH}/:_authToken=${WORKING_TOKEN}
|
||||
//${WORKING_DOMAIN}${REGISTRY_PATH}/:always-auth=true
|
||||
EOF
|
||||
|
||||
for CANDIDATE_NAME in $CANDIDATES; do
|
||||
TOKEN_VAL=$(eval echo "\$$CANDIDATE_NAME")
|
||||
echo "Testing token from $CANDIDATE_NAME (length: ${#TOKEN_VAL})..."
|
||||
|
||||
# 1. Try Bearer
|
||||
if check_url "Bearer" "Authorization: Bearer ${TOKEN_VAL}" "${TEST_URL}"; then
|
||||
echo "✅ Working Bearer token found in $CANDIDATE_NAME."
|
||||
AUTH_TYPE="Bearer"
|
||||
WORKING_TOKEN="${TOKEN_VAL}"
|
||||
break
|
||||
fi
|
||||
|
||||
# 2. Try Basic (token:x-oauth-basic) - Gitea Standard
|
||||
# Encode token:x-oauth-basic
|
||||
BASIC_AUTH=$(echo -n "${TOKEN_VAL}:x-oauth-basic" | base64 | tr -d '\n')
|
||||
if check_url "Basic (token:x-oauth-basic)" "Authorization: Basic ${BASIC_AUTH}" "${TEST_URL}"; then
|
||||
echo "✅ Working Basic (token:x-oauth-basic) found in $CANDIDATE_NAME."
|
||||
AUTH_TYPE="Bearer" # Still use _authToken
|
||||
WORKING_TOKEN="${TOKEN_VAL}"
|
||||
break
|
||||
fi
|
||||
|
||||
# 3. Try Basic (token:empty)
|
||||
BASIC_AUTH_EMPTY=$(echo -n "${TOKEN_VAL}:" | base64 | tr -d '\n')
|
||||
if check_url "Basic (token:)" "Authorization: Basic ${BASIC_AUTH_EMPTY}" "${TEST_URL}"; then
|
||||
echo "✅ Working Basic (token:) found in $CANDIDATE_NAME."
|
||||
AUTH_TYPE="Bearer"
|
||||
WORKING_TOKEN="${TOKEN_VAL}"
|
||||
break
|
||||
fi
|
||||
|
||||
# 4. Try Gitea 'token' header
|
||||
if check_url "Token Header" "Authorization: token ${TOKEN_VAL}" "${TEST_URL}"; then
|
||||
echo "✅ Working Gitea Token header found in $CANDIDATE_NAME."
|
||||
AUTH_TYPE="Bearer"
|
||||
WORKING_TOKEN="${TOKEN_VAL}"
|
||||
break
|
||||
# Add secondary domain if we found one working
|
||||
for DOMAIN in "${DOMAINS[@]}"; do
|
||||
if [ "${DOMAIN}" != "${WORKING_DOMAIN}" ]; then
|
||||
cat >> .npmrc << EOF
|
||||
//${DOMAIN}${REGISTRY_PATH}/:_authToken=${WORKING_TOKEN}
|
||||
//${DOMAIN}${REGISTRY_PATH}/:always-auth=true
|
||||
EOF
|
||||
fi
|
||||
done
|
||||
|
||||
# Generate .npmrc
|
||||
echo "Generating .npmrc..."
|
||||
{
|
||||
echo "always-auth=true"
|
||||
echo "@mintel:registry=https://${REGISTRY_DOMAIN}${REGISTRY_PATH}"
|
||||
|
||||
if [ "$AUTH_TYPE" != "None" ]; then
|
||||
echo "//${REGISTRY_DOMAIN}${REGISTRY_PATH}:_authToken=${WORKING_TOKEN}"
|
||||
echo "//${REGISTRY_DOMAIN}${REGISTRY_PATH}:always-auth=true"
|
||||
# Fallback without trailing slash for some versions of npm/pnpm
|
||||
CLEAN_PATH=$(echo "${REGISTRY_PATH}" | sed 's/\/$//')
|
||||
echo "//${REGISTRY_DOMAIN}${CLEAN_PATH}:_authToken=${WORKING_TOKEN}"
|
||||
echo "✅ .npmrc hardened with verified $CANDIDATE_NAME."
|
||||
else
|
||||
echo "❌ ALL functional tests failed. Falling back to NPM_TOKEN (unverified)."
|
||||
echo "//${REGISTRY_DOMAIN}${REGISTRY_PATH}:_authToken=${NPM_TOKEN}"
|
||||
fi
|
||||
} > .npmrc
|
||||
|
||||
# Debug summary
|
||||
echo "Final .npmrc configuration (masked):"
|
||||
cat .npmrc | sed 's/_authToken=.*/_authToken=********/'
|
||||
echo "✅ .npmrc hardened with verified token on ${WORKING_DOMAIN}."
|
||||
echo "--- Generated .npmrc (masked) ---"
|
||||
sed 's/_authToken=.*/_authToken=********/' .npmrc
|
||||
echo "--------------------------------"
|
||||
|
||||
Reference in New Issue
Block a user