#!/bin/bash source ./send_email.sh # OAuth 2.0 configuration CLIENT_ID="" CLIENT_SECRET="" REDIRECT_URI="http://localhost:3000/api/xoauth/callback" AUTH_URL="https://login.xero.com/identity/connect/authorize" TOKEN_URL="https://identity.xero.com/connect/token" SCOPES="openid profile email accounting.attachments.read accounting.budgets.read accounting.contacts.read accounting.journals.read accounting.reports.read accounting.reports.tenninetynine.read accounting.settings.read accounting.transactions.read assets.read offline_access" REDIS_URL="" save_tokens_to_redis() { local tokens="$1" /usr/local/bin/redis-cli -u "$REDIS_URL" SET xero_tokens "$tokens" } save_state_to_redis() { local state="$1" /usr/local/bin/redis-cli -u "$REDIS_URL" SET xero_state:$state "$state" } get_tokens_from_redis() { /usr/local/bin/redis-cli -u "$REDIS_URL" GET xero_tokens } get_state_from_redis() { local state="$1" /usr/local/bin/redis-cli -u "$REDIS_URL" GET xero_state:$state } generate_auth_url() { STATE=$(openssl rand -hex 16) AUTH_REQUEST_URL="${AUTH_URL}?response_type=code&client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&scope=${SCOPES}&state=${STATE}" save_state_to_redis "$STATE" echo "$AUTH_REQUEST_URL" } refresh_token() { local refresh_token="$1" TOKEN_RESPONSE=$(curl -s -X POST ${TOKEN_URL} \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=refresh_token" \ -d "refresh_token=${refresh_token}" \ -d "client_id=${CLIENT_ID}" \ -d "client_secret=${CLIENT_SECRET}") if echo "$TOKEN_RESPONSE" | jq -e '.access_token' > /dev/null; then echo "Token refreshed successfully." save_tokens_to_redis "$TOKEN_RESPONSE" echo "New tokens saved to Redis." else echo "Error refreshing token. Response:" echo "$TOKEN_RESPONSE" AUTH_URL=$(generate_auth_url) AUTH_URL=$(echo "$AUTH_URL" | sed 's/^OK[[:space:]]*//' | tr -d '\n') TEXT_MESSAGE="Token refresh failed. Please re-authorize: $AUTH_URL" HTML_MESSAGE="Token refresh failed. Please re-authorize" send_email "$TEXT_MESSAGE" "$HTML_MESSAGE" exit 1 fi } exchange_code_for_tokens() { local auth_code="$1" TOKEN_RESPONSE=$(curl -s -X POST ${TOKEN_URL} \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code" \ -d "code=${auth_code}" \ -d "redirect_uri=${REDIRECT_URI}" \ -d "client_id=${CLIENT_ID}" \ -d "client_secret=${CLIENT_SECRET}") if echo "$TOKEN_RESPONSE" | jq -e '.access_token' > /dev/null; then echo "Authorization code exchanged successfully." save_tokens_to_redis "$TOKEN_RESPONSE" echo "Tokens saved to Redis." else echo "Error exchanging authorization code. Response:" echo "$TOKEN_RESPONSE" exit 1 fi } case "$1" in --refresh) echo "Refreshing token..." STORED_TOKENS=$(get_tokens_from_redis) REFRESH_TOKEN=$(echo $STORED_TOKENS | jq -r '.refresh_token') if [ -z "$REFRESH_TOKEN" ]; then echo "Error: Refresh token not found in Redis" AUTH_URL=$(generate_auth_url) AUTH_URL=$(echo "$AUTH_URL" | sed 's/^OK[[:space:]]*//' | tr -d '\n') TEXT_MESSAGE="Refresh token not found in Redis: $REDIS_URL. Please re-authorize: $AUTH_URL" HTML_MESSAGE="Refresh token not found in Redis: $REDIS_URL. Please re-authorize" send_email "$TEXT_MESSAGE" "$HTML_MESSAGE" exit 1 fi refresh_token "$REFRESH_TOKEN" ;; --code) if [ -z "$2" ]; then echo "Error: Authorization code not provided" exit 1 fi echo "Exchanging authorization code for tokens..." exchange_code_for_tokens "$2" ;; "") # Generate a random state value STATE=$(openssl rand -hex 16) # Construct the authorization URL AUTH_REQUEST_URL=$(generate_auth_url) echo "Please visit this URL in a browser on your local machine to authorize the application:" echo $AUTH_REQUEST_URL echo echo "After authorization, you will be redirected to a URL starting with $REDIRECT_URI" echo "Look for the 'code' parameter in this URL." echo # Wait for the authorization code read -p "Enter the authorization code from the redirect URL: " AUTH_CODE exchange_code_for_tokens "$AUTH_CODE" ;; *) echo "Usage: $0 [--refresh | --code ]" exit 1 ;; esac # Use the new access token to update configuration STORED_TOKENS=$(get_tokens_from_redis) NEW_ACCESS_TOKEN=$(echo $STORED_TOKENS | jq -r '.access_token') CURL_RESPONSE=$(curl --request PATCH \ --url 'http://localhost:8000/api/public/v1/sources/' \ --header 'accept: application/json' \ --header 'authorization: Basic base64(username:password)' \ --header 'Content-Type: application/json' \ --data "{ \"configuration\": { \"credentials\": { \"access_token\": \"$NEW_ACCESS_TOKEN\" } } }") echo "CURL Response:" echo "$CURL_RESPONSE" if echo "$CURL_RESPONSE" | jq -e '.sourceId' > /dev/null; then echo "Configuration updated successfully." echo "Updated source details:" echo "$CURL_RESPONSE" | jq '.' else echo "Error updating configuration. Response:" echo "$CURL_RESPONSE" send_email "Error updating configuration: $CURL_RESPONSE" "Error updating configuration: $CURL_RESPONSE" fi