From 17528ef108076b2867712085ac16985bacc3e43e Mon Sep 17 00:00:00 2001 From: Digz0 Date: Fri, 15 May 2026 06:31:50 +0800 Subject: [PATCH 1/4] Harden service token configuration --- common/components/EventManager.php | 9 ++- common/components/Yeaster.php | 10 +-- docs/setup.md | 18 ++++- .../circle-ci/common/config/main-local.php | 4 +- .../common/config/main-local.php | 4 +- .../common/config/main-local.php | 4 +- .../common/config/main-local.php | 4 +- .../dev-server/common/config/main-local.php | 4 +- environments/dev/common/config/main-local.php | 4 +- .../docker/common/config/main-local.php | 4 +- .../krushn-nginx/common/config/main-local.php | 4 +- .../krushn/common/config/main-local.php | 4 +- .../prod-nginx/common/config/main-local.php | 4 +- .../prod-railway/common/config/main-local.php | 4 +- .../prod/common/config/main-local.php | 4 +- scripts/check-service-token-hardening.py | 70 +++++++++++++++++++ staff/web/build/p-5e3b44c4.entry.js | 2 +- 17 files changed, 136 insertions(+), 21 deletions(-) create mode 100644 scripts/check-service-token-hardening.py diff --git a/common/components/EventManager.php b/common/components/EventManager.php index 721a64f64..12d7629cb 100644 --- a/common/components/EventManager.php +++ b/common/components/EventManager.php @@ -51,6 +51,11 @@ class EventManager extends Component */ public $sqsEndpoint; + /** + * @var string|null bearer token for the event microservice endpoint + */ + public $sqsEndpointApiKey; + /** * @var string Mixpanel key */ @@ -406,7 +411,7 @@ public function call($method, $url, $data = []) { ->setFormat(Client::FORMAT_JSON) ->setData($data) ->addHeaders([ - 'Authorization' =>'Bearer QstN8_18LmILpl37r2zvdDCp5JjWPCNh', + 'Authorization' => 'Bearer ' . (string) $this->sqsEndpointApiKey, "Content-Type" => "application/json", 'User-Agent' => 'request', ]) @@ -421,4 +426,4 @@ public function flush() if($this->segmentKey) Segment::flush(); } -} \ No newline at end of file +} diff --git a/common/components/Yeaster.php b/common/components/Yeaster.php index 2f4465dbb..3078cd48a 100644 --- a/common/components/Yeaster.php +++ b/common/components/Yeaster.php @@ -12,7 +12,7 @@ */ class Yeaster extends \yii\base\Component { - public $microserviceApiKey = "QstN8_18LmILpl37r2zvdDCp5JjWPCNh"; + public $microserviceApiKey; //point to microservice handling voicemails, overriding from main-local.php public $apiEndpoint = "http://localhost:3001"; @@ -25,7 +25,7 @@ public function listVoicemails($page, $limit = 10) { ->setUrl($this->apiEndpoint . '/list?page=' . $page . '&limit=' . $limit) ->setFormat(Client::FORMAT_JSON) ->addHeaders([ - 'Authorization' => 'Bearer ' . $this->microserviceApiKey, + 'Authorization' => 'Bearer ' . (string) $this->microserviceApiKey, 'content-type' => 'application/json', ]) ->send(); @@ -41,7 +41,7 @@ public function viewVoicemail($id) { ->setUrl($this->apiEndpoint . '/view/'. $id) ->setFormat(Client::FORMAT_JSON) ->addHeaders([ - 'Authorization' => 'Bearer ' . $this->microserviceApiKey, + 'Authorization' => 'Bearer ' . (string) $this->microserviceApiKey, 'content-type' => 'application/json', ]) ->send(); @@ -57,11 +57,11 @@ public function downloadVoicemail($id) { ->setUrl($this->apiEndpoint . '/download/'. $id) ->setFormat(Client::FORMAT_JSON) ->addHeaders([ - 'Authorization' => 'Bearer ' . $this->microserviceApiKey, + 'Authorization' => 'Bearer ' . (string) $this->microserviceApiKey, 'content-type' => 'application/json', ]) ->send(); return $response->content; } -} \ No newline at end of file +} diff --git a/docs/setup.md b/docs/setup.md index 53550fa5f..7150b033a 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -31,6 +31,22 @@ Use the provided script in the project root: ./run-tests.sh ``` +### Service Integration Secrets + +Keep service API tokens in deployment environment variables instead of checked-in +config files or browser bundles: + +```bash +WALLET_API_KEY= +YEASTER_MICROSERVICE_API_KEY= +EVENT_MANAGER_ENDPOINT_API_KEY= +``` + +`WALLET_API_KEY` is used by the legacy wallet integration when enabled. +`YEASTER_MICROSERVICE_API_KEY` authenticates voicemail microservice requests. +`EVENT_MANAGER_ENDPOINT_API_KEY` authenticates EventManager calls to the SQS +bridge endpoint when `sqsEndpoint` is configured. + ## Server Requirements ### PHP Extensions @@ -56,4 +72,4 @@ cd console && ../yii algolia/index candidate ```bash ./yii cron/update-candidate-stats ./yii cron/update-company-stats -``` \ No newline at end of file +``` diff --git a/environments/circle-ci/common/config/main-local.php b/environments/circle-ci/common/config/main-local.php index 3950e0d03..9b89833ae 100644 --- a/environments/circle-ci/common/config/main-local.php +++ b/environments/circle-ci/common/config/main-local.php @@ -17,12 +17,13 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => 'QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG', + 'apiKey' => getenv('WALLET_API_KEY'), 'apiEndpoint' => 'https://webhook.dev.wallet.bawes.net/v1', 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], 'yeaster' => [ 'class' => 'common\components\Yeaster', + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), "apiEndpoint" => "http://localhost:3001" ], 'mailer' => [ @@ -53,6 +54,7 @@ ], 'eventManager' => [ 'class' => 'common\components\EventManager', + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), "sqsRagion" => "eu-west-2", "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", "sqsSecret" => "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", diff --git a/environments/dev-server-nginx-debug/common/config/main-local.php b/environments/dev-server-nginx-debug/common/config/main-local.php index 16ca69de9..3f3b50036 100644 --- a/environments/dev-server-nginx-debug/common/config/main-local.php +++ b/environments/dev-server-nginx-debug/common/config/main-local.php @@ -17,12 +17,13 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => 'QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG', + 'apiKey' => getenv('WALLET_API_KEY'), 'apiEndpoint' => 'https://webhook.dev.wallet.bawes.net/v1', 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], 'yeaster' => [ 'class' => 'common\components\Yeaster', + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), "apiEndpoint" => "http://localhost:3001" ], 'xero' => [ @@ -84,6 +85,7 @@ ],*/ 'eventManager' => [ 'class' => 'common\components\EventManager', + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), "sqsRagion" => "eu-west-2", "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", "sqsSecret" => "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", diff --git a/environments/dev-server-nginx/common/config/main-local.php b/environments/dev-server-nginx/common/config/main-local.php index e0a79505f..aead75ae5 100644 --- a/environments/dev-server-nginx/common/config/main-local.php +++ b/environments/dev-server-nginx/common/config/main-local.php @@ -17,12 +17,13 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => 'QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG', + 'apiKey' => getenv('WALLET_API_KEY'), 'apiEndpoint' => 'https://webhook.dev.wallet.bawes.net/v1', 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], 'yeaster' => [ 'class' => 'common\components\Yeaster', + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), "apiEndpoint" => "http://localhost:3001" ], 'xero' => [ @@ -82,6 +83,7 @@ ],*/ 'eventManager' => [ 'class' => 'common\components\EventManager', + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), "sqsRagion" => "eu-west-2", "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", "sqsSecret" => "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", diff --git a/environments/dev-server-railway/common/config/main-local.php b/environments/dev-server-railway/common/config/main-local.php index e9d8bc3ce..7f51a4be2 100644 --- a/environments/dev-server-railway/common/config/main-local.php +++ b/environments/dev-server-railway/common/config/main-local.php @@ -18,13 +18,14 @@ //todo: replace with wallet from sandbox 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => 'QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG', + 'apiKey' => getenv('WALLET_API_KEY'), 'apiEndpoint' => 'https://webhook.dev.wallet.bawes.net/v1', 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], //todo: replace with yeaster from sandbox 'yeaster' => [ 'class' => 'common\components\Yeaster', + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), "apiEndpoint" => "http://localhost:3001" ], 'xero' => [ @@ -86,6 +87,7 @@ ],*/ 'eventManager' => [ 'class' => 'common\components\EventManager', + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), "sqsRagion" => "eu-west-2", "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", "sqsSecret" => "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", diff --git a/environments/dev-server/common/config/main-local.php b/environments/dev-server/common/config/main-local.php index ee588a95f..2852a1c58 100644 --- a/environments/dev-server/common/config/main-local.php +++ b/environments/dev-server/common/config/main-local.php @@ -17,12 +17,13 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => 'QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG', + 'apiKey' => getenv('WALLET_API_KEY'), 'apiEndpoint' => 'https://webhook.dev.wallet.bawes.net/v1', 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], 'yeaster' => [ 'class' => 'common\components\Yeaster', + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), "apiEndpoint" => "http://localhost:3001" ], 'xero' => [ @@ -87,6 +88,7 @@ ],*/ 'eventManager' => [ 'class' => 'common\components\EventManager', + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), "sqsRagion" => "eu-west-2", "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", "sqsSecret" => "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", diff --git a/environments/dev/common/config/main-local.php b/environments/dev/common/config/main-local.php index 75e6afd0b..381766f39 100644 --- a/environments/dev/common/config/main-local.php +++ b/environments/dev/common/config/main-local.php @@ -17,12 +17,13 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => 'QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG', + 'apiKey' => getenv('WALLET_API_KEY'), 'apiEndpoint' => 'http://localhost/wallet/webhook/web/v1',//todo: 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], 'yeaster' => [ 'class' => 'common\components\Yeaster', + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), "apiEndpoint" => "http://localhost:3001" ], 'cache' => [ @@ -66,6 +67,7 @@ ], 'eventManager' => [ 'class' => 'common\components\EventManager', + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), "sqsRagion" => "eu-west-2", "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", "sqsSecret" => "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", diff --git a/environments/docker/common/config/main-local.php b/environments/docker/common/config/main-local.php index 2e5d08211..a90872c2d 100644 --- a/environments/docker/common/config/main-local.php +++ b/environments/docker/common/config/main-local.php @@ -27,6 +27,7 @@ ], 'yeaster' => [ 'class' => 'common\components\Yeaster', + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), "apiEndpoint" => "http://192.168.1.5:3001" ], 'xero' => [ @@ -41,7 +42,7 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => 'QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG', + 'apiKey' => getenv('WALLET_API_KEY'), 'apiEndpoint' => 'http://192.168.1.5/wallet/webhook/web/v1', 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], @@ -73,6 +74,7 @@ ], 'eventManager' => [ 'class' => 'common\components\EventManager', + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), "sqsRagion" => "eu-west-2", "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", "sqsSecret" => "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", diff --git a/environments/krushn-nginx/common/config/main-local.php b/environments/krushn-nginx/common/config/main-local.php index 8573aa6bb..34883e169 100644 --- a/environments/krushn-nginx/common/config/main-local.php +++ b/environments/krushn-nginx/common/config/main-local.php @@ -10,6 +10,7 @@ ], 'yeaster' => [ 'class' => 'common\components\Yeaster', + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), "apiEndpoint" => "http://localhost:3001" ], 'walletDb' => [ @@ -41,7 +42,7 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => 'QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG', + 'apiKey' => getenv('WALLET_API_KEY'), 'apiEndpoint' => 'http://localhost/wallet/webhook/web/v1', 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], @@ -74,6 +75,7 @@ ], 'eventManager' => [ 'class' => 'common\components\EventManager', + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), // "sqsRagion" => "eu-west-2", // "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", // "sqsSecret" => "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", diff --git a/environments/krushn/common/config/main-local.php b/environments/krushn/common/config/main-local.php index 6a2fb61a1..00563c1a7 100644 --- a/environments/krushn/common/config/main-local.php +++ b/environments/krushn/common/config/main-local.php @@ -10,6 +10,7 @@ ], 'yeaster' => [ 'class' => 'common\components\Yeaster', + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), "apiEndpoint" => "http://localhost:3001" ], 'walletDb' => [ @@ -41,7 +42,7 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => 'QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG', + 'apiKey' => getenv('WALLET_API_KEY'), 'apiEndpoint' => 'http://localhost/wallet/webhook/web/v1', 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], @@ -73,6 +74,7 @@ ], 'eventManager' => [ 'class' => 'common\components\EventManager', + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), // "sqsRagion" => "eu-west-2", // "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", // "sqsSecret" => "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", diff --git a/environments/prod-nginx/common/config/main-local.php b/environments/prod-nginx/common/config/main-local.php index b5c8b2841..fb1b0b5de 100644 --- a/environments/prod-nginx/common/config/main-local.php +++ b/environments/prod-nginx/common/config/main-local.php @@ -52,7 +52,7 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => 'POAO-BiBxj-Oqp2XOIDZgSDrTYJxOa3M', + 'apiKey' => getenv('WALLET_API_KEY'), ], 'redis' => [ 'class' => 'yii\redis\Connection', @@ -142,6 +142,7 @@ ],*/ 'eventManager' => [ 'class' => 'common\components\EventManager', + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), //todo: commenting down as it's slowing down all apis //"sqsRagion" => "eu-west-2", //"sqsKey" => "AKIAWMITDJRKXNWDOBNJ", @@ -179,6 +180,7 @@ ], 'yeaster' => [ 'class' => 'common\components\Yeaster', + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), "apiEndpoint" => "http://ec2-18-130-75-235.eu-west-2.compute.amazonaws.com:3001" ], 'urlManagerStaff' => [ diff --git a/environments/prod-railway/common/config/main-local.php b/environments/prod-railway/common/config/main-local.php index f8b14d079..99d5cd919 100644 --- a/environments/prod-railway/common/config/main-local.php +++ b/environments/prod-railway/common/config/main-local.php @@ -30,7 +30,7 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => 'POAO-BiBxj-Oqp2XOIDZgSDrTYJxOa3M', + 'apiKey' => getenv('WALLET_API_KEY'), ], 'redis' => [ 'class' => 'yii\redis\Connection', @@ -126,6 +126,7 @@ ],*/ 'eventManager' => [ 'class' => 'common\components\EventManager', + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), //todo: commenting down as it's slowing down all apis //"sqsRagion" => "eu-west-2", //"sqsKey" => "AKIAWMITDJRKXNWDOBNJ", @@ -167,6 +168,7 @@ ], 'yeaster' => [ 'class' => 'common\components\Yeaster', + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), "apiEndpoint" => "http://ec2-18-130-75-235.eu-west-2.compute.amazonaws.com:3001" ], 'urlManagerStaff' => [ diff --git a/environments/prod/common/config/main-local.php b/environments/prod/common/config/main-local.php index d8f901035..bbf3470fd 100644 --- a/environments/prod/common/config/main-local.php +++ b/environments/prod/common/config/main-local.php @@ -52,7 +52,7 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => 'imx4kpyVCXbi7sVy-zEvEITL63sQWisn',//QSw2ByGUITXFNjJVNNjyzxdbvYP9rXbG + 'apiKey' => getenv('WALLET_API_KEY') ], 'redis' => [ 'class' => 'yii\redis\Connection', @@ -128,6 +128,7 @@ ],*/ 'eventManager' => [ 'class' => 'common\components\EventManager', + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), //todo: commenting down as it's slowing down all apis //"sqsRagion" => "eu-west-2", //"sqsKey" => "AKIAWMITDJRKXNWDOBNJ", @@ -165,6 +166,7 @@ ], 'yeaster' => [ 'class' => 'common\components\Yeaster', + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), "apiEndpoint" => "http://ec2-18-130-75-235.eu-west-2.compute.amazonaws.com:3001" ], 'urlManagerStaff' => [ diff --git a/scripts/check-service-token-hardening.py b/scripts/check-service-token-hardening.py new file mode 100644 index 000000000..070be347f --- /dev/null +++ b/scripts/check-service-token-hardening.py @@ -0,0 +1,70 @@ +from pathlib import Path +import re +import sys + +ROOT = Path(__file__).resolve().parents[1] + +SECRET_PATTERNS = [ + ("raw microservice bearer token", re.compile(r"Bearer\s+[A-Za-z0-9_-]{24,}")), + ("browser-bundled Xero bearer token", re.compile(r"Bearer\s+eyJhbGciOiJSUzI1NiIsImtpZCI6")), +] + +REQUIRED_ENV_REFERENCES = [ + ("WALLET_API_KEY", ROOT / "environments"), + ("YEASTER_MICROSERVICE_API_KEY", ROOT / "environments"), + ("EVENT_MANAGER_ENDPOINT_API_KEY", ROOT / "environments"), +] + +SEARCH_SUFFIXES = {".php", ".js", ".md", ".yml", ".yaml", ".json"} +SKIP_DIRS = {".git", "vendor"} + + +def iter_files(): + for path in ROOT.rglob("*"): + if not path.is_file() or path.suffix not in SEARCH_SUFFIXES: + continue + if any(part in SKIP_DIRS for part in path.parts): + continue + yield path + + +def main(): + failures = [] + for path in iter_files(): + text = path.read_text(encoding="utf-8", errors="ignore") + rel = path.relative_to(ROOT) + for label, pattern in SECRET_PATTERNS: + if pattern.search(text): + failures.append(f"{rel}: contains {label}") + + wallet_literal = re.compile( + r"'walletManager'\s*=>\s*\[[\s\S]*?'apiKey'\s*=>\s*'(?!\s*\))", + re.MULTILINE, + ) + for path in (ROOT / "environments").rglob("main-local.php"): + text = path.read_text(encoding="utf-8", errors="ignore") + if wallet_literal.search(text): + failures.append(f"{path.relative_to(ROOT)}: walletManager apiKey is not env-backed") + + for env_name, base in REQUIRED_ENV_REFERENCES: + found = False + for path in base.rglob("*.php"): + text = path.read_text(encoding="utf-8", errors="ignore") + if env_name in text: + found = True + break + if not found: + failures.append(f"missing environment reference: {env_name}") + + if failures: + print("Service token hardening check failed:") + for failure in failures: + print(f"- {failure}") + return 1 + + print("Service token hardening check passed.") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/staff/web/build/p-5e3b44c4.entry.js b/staff/web/build/p-5e3b44c4.entry.js index 5df2b1f29..58c4167ef 100644 --- a/staff/web/build/p-5e3b44c4.entry.js +++ b/staff/web/build/p-5e3b44c4.entry.js @@ -1 +1 @@ -import{r as o,h as t,H as e}from"./p-a94aef08.js";const r=class{constructor(t){o(this,t)}componentWillLoad(){const o=new Headers;return o.set("Content-Type","application/json"),o.set("Authorization","Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjFDQUY4RTY2NzcyRDZEQzAyOEQ2NzI2RkQwMjYxNTgxNTcwRUZDMTkiLCJ0eXAiOiJKV1QiLCJ4NXQiOiJISy1PWm5jdGJjQW8xbkp2MENZVmdWY09fQmsifQ"),fetch("https://api.xero.com/api.xro/2.0/Reports/ProfitAndLoss",{headers:o}).then((o=>o.json())).then((o=>{console.log(o),this.profitData=o}))}render(){return t(e,null,"Xero test")}};r.style=":host{display:block}";export{r as xero_profit} \ No newline at end of file +import{r as o,h as t,H as e}from"./p-a94aef08.js";const r=class{constructor(t){o(this,t)}componentWillLoad(){this.profitData=null}render(){return t(e,null,"Xero test disabled")}};r.style=":host{display:block}";export{r as xero_profit} From 037e49e2243877bb1b9dc58ad0e052d5b740be9d Mon Sep 17 00:00:00 2001 From: Digz0 Date: Fri, 15 May 2026 06:53:20 +0800 Subject: [PATCH 2/4] Address service token review feedback --- common/components/EventManager.php | 7 ++++- common/components/Yeaster.php | 28 +++++++++++-------- docs/setup.md | 12 ++++++++ .../circle-ci/common/config/main-local.php | 6 ++-- .../common/config/main-local.php | 6 ++-- .../common/config/main-local.php | 6 ++-- .../common/config/main-local.php | 6 ++-- .../dev-server/common/config/main-local.php | 6 ++-- environments/dev/common/config/main-local.php | 6 ++-- .../docker/common/config/main-local.php | 6 ++-- .../krushn-nginx/common/config/main-local.php | 6 ++-- .../krushn/common/config/main-local.php | 6 ++-- .../prod-nginx/common/config/main-local.php | 6 ++-- .../prod-railway/common/config/main-local.php | 6 ++-- .../prod/common/config/main-local.php | 6 ++-- scripts/check-service-token-hardening.py | 11 ++++++-- 16 files changed, 79 insertions(+), 51 deletions(-) diff --git a/common/components/EventManager.php b/common/components/EventManager.php index 12d7629cb..506137ca4 100644 --- a/common/components/EventManager.php +++ b/common/components/EventManager.php @@ -5,6 +5,7 @@ use Segment\Segment; use Yii; use yii\base\Component; +use yii\base\InvalidConfigException; use Aws\Sqs\SqsClient; use Aws\Exception\AwsException; use yii\httpclient\Client; @@ -403,6 +404,10 @@ public function track($event, $eventData, $timestamp = null, $userId = null, $on * API call for webhook */ public function call($method, $url, $data = []) { + if (trim((string) $this->sqsEndpointApiKey) === '') { + throw new InvalidConfigException('EVENT_MANAGER_ENDPOINT_API_KEY must be configured before sending SQS endpoint events.'); + } + $client = new Client(); return $client->createRequest() @@ -411,7 +416,7 @@ public function call($method, $url, $data = []) { ->setFormat(Client::FORMAT_JSON) ->setData($data) ->addHeaders([ - 'Authorization' => 'Bearer ' . (string) $this->sqsEndpointApiKey, + 'Authorization' => 'Bearer ' . $this->sqsEndpointApiKey, "Content-Type" => "application/json", 'User-Agent' => 'request', ]) diff --git a/common/components/Yeaster.php b/common/components/Yeaster.php index 3078cd48a..2c4062747 100644 --- a/common/components/Yeaster.php +++ b/common/components/Yeaster.php @@ -2,6 +2,7 @@ namespace common\components; +use yii\base\InvalidConfigException; use yii\httpclient\Client; /** @@ -17,6 +18,18 @@ class Yeaster extends \yii\base\Component //point to microservice handling voicemails, overriding from main-local.php public $apiEndpoint = "http://localhost:3001"; + private function authorizationHeaders() + { + if (trim((string) $this->microserviceApiKey) === '') { + throw new InvalidConfigException('YEASTER_MICROSERVICE_API_KEY must be configured before calling the voicemail microservice.'); + } + + return [ + 'Authorization' => 'Bearer ' . $this->microserviceApiKey, + 'content-type' => 'application/json', + ]; + } + public function listVoicemails($page, $limit = 10) { $client = new Client(); @@ -24,10 +37,7 @@ public function listVoicemails($page, $limit = 10) { ->setMethod('GET') ->setUrl($this->apiEndpoint . '/list?page=' . $page . '&limit=' . $limit) ->setFormat(Client::FORMAT_JSON) - ->addHeaders([ - 'Authorization' => 'Bearer ' . (string) $this->microserviceApiKey, - 'content-type' => 'application/json', - ]) + ->addHeaders($this->authorizationHeaders()) ->send(); return $response->getData(); @@ -40,10 +50,7 @@ public function viewVoicemail($id) { ->setMethod('GET') ->setUrl($this->apiEndpoint . '/view/'. $id) ->setFormat(Client::FORMAT_JSON) - ->addHeaders([ - 'Authorization' => 'Bearer ' . (string) $this->microserviceApiKey, - 'content-type' => 'application/json', - ]) + ->addHeaders($this->authorizationHeaders()) ->send(); return $response->content; @@ -56,10 +63,7 @@ public function downloadVoicemail($id) { ->setMethod('GET') ->setUrl($this->apiEndpoint . '/download/'. $id) ->setFormat(Client::FORMAT_JSON) - ->addHeaders([ - 'Authorization' => 'Bearer ' . (string) $this->microserviceApiKey, - 'content-type' => 'application/json', - ]) + ->addHeaders($this->authorizationHeaders()) ->send(); return $response->content; diff --git a/docs/setup.md b/docs/setup.md index 7150b033a..3c3e6bf5a 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -47,6 +47,18 @@ EVENT_MANAGER_ENDPOINT_API_KEY= `EVENT_MANAGER_ENDPOINT_API_KEY` authenticates EventManager calls to the SQS bridge endpoint when `sqsEndpoint` is configured. +Configure these values in each deployment environment that enables the +corresponding integration. Production and shared staging environments should use +provider-issued tokens from the wallet service, voicemail microservice, and SQS +bridge service owners; local development can leave an integration unset only +when that feature is not exercised. + +Missing values are treated as disabled or invalid credentials. Wallet requests +must not be sent without `WALLET_API_KEY`. Voicemail calls fail fast before +emitting an empty `Authorization` header when `YEASTER_MICROSERVICE_API_KEY` is +missing. EventManager calls to the SQS bridge fail fast when +`EVENT_MANAGER_ENDPOINT_API_KEY` is missing and `sqsEndpoint` is configured. + ## Server Requirements ### PHP Extensions diff --git a/environments/circle-ci/common/config/main-local.php b/environments/circle-ci/common/config/main-local.php index 9b89833ae..9d8e53ecf 100644 --- a/environments/circle-ci/common/config/main-local.php +++ b/environments/circle-ci/common/config/main-local.php @@ -17,13 +17,13 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => getenv('WALLET_API_KEY'), + 'apiKey' => getenv('WALLET_API_KEY') ?: null, 'apiEndpoint' => 'https://webhook.dev.wallet.bawes.net/v1', 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], 'yeaster' => [ 'class' => 'common\components\Yeaster', - 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null, "apiEndpoint" => "http://localhost:3001" ], 'mailer' => [ @@ -54,7 +54,7 @@ ], 'eventManager' => [ 'class' => 'common\components\EventManager', - 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null, "sqsRagion" => "eu-west-2", "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", "sqsSecret" => "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", diff --git a/environments/dev-server-nginx-debug/common/config/main-local.php b/environments/dev-server-nginx-debug/common/config/main-local.php index 3f3b50036..7b6936b46 100644 --- a/environments/dev-server-nginx-debug/common/config/main-local.php +++ b/environments/dev-server-nginx-debug/common/config/main-local.php @@ -17,13 +17,13 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => getenv('WALLET_API_KEY'), + 'apiKey' => getenv('WALLET_API_KEY') ?: null, 'apiEndpoint' => 'https://webhook.dev.wallet.bawes.net/v1', 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], 'yeaster' => [ 'class' => 'common\components\Yeaster', - 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null, "apiEndpoint" => "http://localhost:3001" ], 'xero' => [ @@ -85,7 +85,7 @@ ],*/ 'eventManager' => [ 'class' => 'common\components\EventManager', - 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null, "sqsRagion" => "eu-west-2", "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", "sqsSecret" => "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", diff --git a/environments/dev-server-nginx/common/config/main-local.php b/environments/dev-server-nginx/common/config/main-local.php index aead75ae5..e0c77ba35 100644 --- a/environments/dev-server-nginx/common/config/main-local.php +++ b/environments/dev-server-nginx/common/config/main-local.php @@ -17,13 +17,13 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => getenv('WALLET_API_KEY'), + 'apiKey' => getenv('WALLET_API_KEY') ?: null, 'apiEndpoint' => 'https://webhook.dev.wallet.bawes.net/v1', 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], 'yeaster' => [ 'class' => 'common\components\Yeaster', - 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null, "apiEndpoint" => "http://localhost:3001" ], 'xero' => [ @@ -83,7 +83,7 @@ ],*/ 'eventManager' => [ 'class' => 'common\components\EventManager', - 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null, "sqsRagion" => "eu-west-2", "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", "sqsSecret" => "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", diff --git a/environments/dev-server-railway/common/config/main-local.php b/environments/dev-server-railway/common/config/main-local.php index 7f51a4be2..fbce2af41 100644 --- a/environments/dev-server-railway/common/config/main-local.php +++ b/environments/dev-server-railway/common/config/main-local.php @@ -18,14 +18,14 @@ //todo: replace with wallet from sandbox 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => getenv('WALLET_API_KEY'), + 'apiKey' => getenv('WALLET_API_KEY') ?: null, 'apiEndpoint' => 'https://webhook.dev.wallet.bawes.net/v1', 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], //todo: replace with yeaster from sandbox 'yeaster' => [ 'class' => 'common\components\Yeaster', - 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null, "apiEndpoint" => "http://localhost:3001" ], 'xero' => [ @@ -87,7 +87,7 @@ ],*/ 'eventManager' => [ 'class' => 'common\components\EventManager', - 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null, "sqsRagion" => "eu-west-2", "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", "sqsSecret" => "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", diff --git a/environments/dev-server/common/config/main-local.php b/environments/dev-server/common/config/main-local.php index 2852a1c58..2efdd412e 100644 --- a/environments/dev-server/common/config/main-local.php +++ b/environments/dev-server/common/config/main-local.php @@ -17,13 +17,13 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => getenv('WALLET_API_KEY'), + 'apiKey' => getenv('WALLET_API_KEY') ?: null, 'apiEndpoint' => 'https://webhook.dev.wallet.bawes.net/v1', 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], 'yeaster' => [ 'class' => 'common\components\Yeaster', - 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null, "apiEndpoint" => "http://localhost:3001" ], 'xero' => [ @@ -88,7 +88,7 @@ ],*/ 'eventManager' => [ 'class' => 'common\components\EventManager', - 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null, "sqsRagion" => "eu-west-2", "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", "sqsSecret" => "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", diff --git a/environments/dev/common/config/main-local.php b/environments/dev/common/config/main-local.php index 381766f39..c8a8fc7eb 100644 --- a/environments/dev/common/config/main-local.php +++ b/environments/dev/common/config/main-local.php @@ -17,13 +17,13 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => getenv('WALLET_API_KEY'), + 'apiKey' => getenv('WALLET_API_KEY') ?: null, 'apiEndpoint' => 'http://localhost/wallet/webhook/web/v1',//todo: 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], 'yeaster' => [ 'class' => 'common\components\Yeaster', - 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null, "apiEndpoint" => "http://localhost:3001" ], 'cache' => [ @@ -67,7 +67,7 @@ ], 'eventManager' => [ 'class' => 'common\components\EventManager', - 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null, "sqsRagion" => "eu-west-2", "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", "sqsSecret" => "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", diff --git a/environments/docker/common/config/main-local.php b/environments/docker/common/config/main-local.php index a90872c2d..b37c889a3 100644 --- a/environments/docker/common/config/main-local.php +++ b/environments/docker/common/config/main-local.php @@ -27,7 +27,7 @@ ], 'yeaster' => [ 'class' => 'common\components\Yeaster', - 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null, "apiEndpoint" => "http://192.168.1.5:3001" ], 'xero' => [ @@ -42,7 +42,7 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => getenv('WALLET_API_KEY'), + 'apiKey' => getenv('WALLET_API_KEY') ?: null, 'apiEndpoint' => 'http://192.168.1.5/wallet/webhook/web/v1', 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], @@ -74,7 +74,7 @@ ], 'eventManager' => [ 'class' => 'common\components\EventManager', - 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null, "sqsRagion" => "eu-west-2", "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", "sqsSecret" => "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", diff --git a/environments/krushn-nginx/common/config/main-local.php b/environments/krushn-nginx/common/config/main-local.php index 34883e169..36cd91612 100644 --- a/environments/krushn-nginx/common/config/main-local.php +++ b/environments/krushn-nginx/common/config/main-local.php @@ -10,7 +10,7 @@ ], 'yeaster' => [ 'class' => 'common\components\Yeaster', - 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null, "apiEndpoint" => "http://localhost:3001" ], 'walletDb' => [ @@ -42,7 +42,7 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => getenv('WALLET_API_KEY'), + 'apiKey' => getenv('WALLET_API_KEY') ?: null, 'apiEndpoint' => 'http://localhost/wallet/webhook/web/v1', 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], @@ -75,7 +75,7 @@ ], 'eventManager' => [ 'class' => 'common\components\EventManager', - 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null, // "sqsRagion" => "eu-west-2", // "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", // "sqsSecret" => "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", diff --git a/environments/krushn/common/config/main-local.php b/environments/krushn/common/config/main-local.php index 00563c1a7..f134c41ae 100644 --- a/environments/krushn/common/config/main-local.php +++ b/environments/krushn/common/config/main-local.php @@ -10,7 +10,7 @@ ], 'yeaster' => [ 'class' => 'common\components\Yeaster', - 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null, "apiEndpoint" => "http://localhost:3001" ], 'walletDb' => [ @@ -42,7 +42,7 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => getenv('WALLET_API_KEY'), + 'apiKey' => getenv('WALLET_API_KEY') ?: null, 'apiEndpoint' => 'http://localhost/wallet/webhook/web/v1', 'companyWalletUserID' => 'user_fcac8a5f-52a2-11ed-a68e-d85ed3a264df' ], @@ -74,7 +74,7 @@ ], 'eventManager' => [ 'class' => 'common\components\EventManager', - 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null, // "sqsRagion" => "eu-west-2", // "sqsKey" => "AKIAWMITDJRKXNWDOBNJ", // "sqsSecret" => "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", diff --git a/environments/prod-nginx/common/config/main-local.php b/environments/prod-nginx/common/config/main-local.php index fb1b0b5de..c5caf1578 100644 --- a/environments/prod-nginx/common/config/main-local.php +++ b/environments/prod-nginx/common/config/main-local.php @@ -52,7 +52,7 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => getenv('WALLET_API_KEY'), + 'apiKey' => getenv('WALLET_API_KEY') ?: null, ], 'redis' => [ 'class' => 'yii\redis\Connection', @@ -142,7 +142,7 @@ ],*/ 'eventManager' => [ 'class' => 'common\components\EventManager', - 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null, //todo: commenting down as it's slowing down all apis //"sqsRagion" => "eu-west-2", //"sqsKey" => "AKIAWMITDJRKXNWDOBNJ", @@ -180,7 +180,7 @@ ], 'yeaster' => [ 'class' => 'common\components\Yeaster', - 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null, "apiEndpoint" => "http://ec2-18-130-75-235.eu-west-2.compute.amazonaws.com:3001" ], 'urlManagerStaff' => [ diff --git a/environments/prod-railway/common/config/main-local.php b/environments/prod-railway/common/config/main-local.php index 99d5cd919..b1b363ba9 100644 --- a/environments/prod-railway/common/config/main-local.php +++ b/environments/prod-railway/common/config/main-local.php @@ -30,7 +30,7 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => getenv('WALLET_API_KEY'), + 'apiKey' => getenv('WALLET_API_KEY') ?: null, ], 'redis' => [ 'class' => 'yii\redis\Connection', @@ -126,7 +126,7 @@ ],*/ 'eventManager' => [ 'class' => 'common\components\EventManager', - 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null, //todo: commenting down as it's slowing down all apis //"sqsRagion" => "eu-west-2", //"sqsKey" => "AKIAWMITDJRKXNWDOBNJ", @@ -168,7 +168,7 @@ ], 'yeaster' => [ 'class' => 'common\components\Yeaster', - 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null, "apiEndpoint" => "http://ec2-18-130-75-235.eu-west-2.compute.amazonaws.com:3001" ], 'urlManagerStaff' => [ diff --git a/environments/prod/common/config/main-local.php b/environments/prod/common/config/main-local.php index bbf3470fd..7c9103f99 100644 --- a/environments/prod/common/config/main-local.php +++ b/environments/prod/common/config/main-local.php @@ -52,7 +52,7 @@ ], 'walletManager' => [ 'class' => 'common\components\WalletManager', - 'apiKey' => getenv('WALLET_API_KEY') + 'apiKey' => getenv('WALLET_API_KEY') ?: null ], 'redis' => [ 'class' => 'yii\redis\Connection', @@ -128,7 +128,7 @@ ],*/ 'eventManager' => [ 'class' => 'common\components\EventManager', - 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY'), + 'sqsEndpointApiKey' => getenv('EVENT_MANAGER_ENDPOINT_API_KEY') ?: null, //todo: commenting down as it's slowing down all apis //"sqsRagion" => "eu-west-2", //"sqsKey" => "AKIAWMITDJRKXNWDOBNJ", @@ -166,7 +166,7 @@ ], 'yeaster' => [ 'class' => 'common\components\Yeaster', - 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY'), + 'microserviceApiKey' => getenv('YEASTER_MICROSERVICE_API_KEY') ?: null, "apiEndpoint" => "http://ec2-18-130-75-235.eu-west-2.compute.amazonaws.com:3001" ], 'urlManagerStaff' => [ diff --git a/scripts/check-service-token-hardening.py b/scripts/check-service-token-hardening.py index 070be347f..da6bdc28a 100644 --- a/scripts/check-service-token-hardening.py +++ b/scripts/check-service-token-hardening.py @@ -20,6 +20,7 @@ def iter_files(): + """Yield repository files that can contain checked-in service tokens.""" for path in ROOT.rglob("*"): if not path.is_file() or path.suffix not in SEARCH_SUFFIXES: continue @@ -29,6 +30,7 @@ def iter_files(): def main(): + """Validate service tokens are referenced from runtime environment sources.""" failures = [] for path in iter_files(): text = path.read_text(encoding="utf-8", errors="ignore") @@ -38,7 +40,7 @@ def main(): failures.append(f"{rel}: contains {label}") wallet_literal = re.compile( - r"'walletManager'\s*=>\s*\[[\s\S]*?'apiKey'\s*=>\s*'(?!\s*\))", + r"['\"]walletManager['\"]\s*=>\s*\[[\s\S]*?['\"]apiKey['\"]\s*=>\s*['\"](?!\s*\))", re.MULTILINE, ) for path in (ROOT / "environments").rglob("main-local.php"): @@ -48,9 +50,14 @@ def main(): for env_name, base in REQUIRED_ENV_REFERENCES: found = False + env_pattern = re.escape(env_name) + access_pattern = re.compile( + rf"(?:getenv|env)\s*\(\s*['\"]{env_pattern}['\"]\s*\)" + rf"|\$_(?:ENV|SERVER)\s*\[\s*['\"]{env_pattern}['\"]\s*\]" + ) for path in base.rglob("*.php"): text = path.read_text(encoding="utf-8", errors="ignore") - if env_name in text: + if access_pattern.search(text): found = True break if not found: From ae0c3430fceff4d595e119132940e8264274770c Mon Sep 17 00:00:00 2001 From: Digz0 <172674408+digzrow-coder@users.noreply.github.com> Date: Fri, 15 May 2026 10:18:58 +0800 Subject: [PATCH 3/4] Document service token helpers --- common/components/EventManager.php | 11 +++++++++- common/components/Yeaster.php | 32 +++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/common/components/EventManager.php b/common/components/EventManager.php index 506137ca4..83c6abb20 100644 --- a/common/components/EventManager.php +++ b/common/components/EventManager.php @@ -10,6 +10,9 @@ use Aws\Exception\AwsException; use yii\httpclient\Client; +/** + * Coordinates analytics, queue, endpoint, and webhook event delivery. + */ class EventManager extends Component { /** @@ -401,7 +404,13 @@ public function track($event, $eventData, $timestamp = null, $userId = null, $on } /** - * API call for webhook + * Send a JSON request to the configured SQS endpoint with a required bearer token. + * + * @param string $method HTTP method to use + * @param string $url endpoint URL to call + * @param array $data JSON payload to send + * @return \yii\httpclient\Response + * @throws InvalidConfigException when EVENT_MANAGER_ENDPOINT_API_KEY is not configured */ public function call($method, $url, $data = []) { if (trim((string) $this->sqsEndpointApiKey) === '') { diff --git a/common/components/Yeaster.php b/common/components/Yeaster.php index 2c4062747..772f02743 100644 --- a/common/components/Yeaster.php +++ b/common/components/Yeaster.php @@ -13,11 +13,22 @@ */ class Yeaster extends \yii\base\Component { + /** + * @var string|null bearer token used to authenticate calls to the voicemail microservice + */ public $microserviceApiKey; - //point to microservice handling voicemails, overriding from main-local.php + /** + * @var string base URL for the voicemail microservice, overridden from main-local.php + */ public $apiEndpoint = "http://localhost:3001"; + /** + * Build authenticated request headers and fail fast if the service token is missing. + * + * @return array + * @throws InvalidConfigException when YEASTER_MICROSERVICE_API_KEY is not configured + */ private function authorizationHeaders() { if (trim((string) $this->microserviceApiKey) === '') { @@ -30,6 +41,13 @@ private function authorizationHeaders() ]; } + /** + * Fetch a paginated voicemail listing from the Yeaster microservice. + * + * @param int $page page number to request + * @param int $limit maximum number of voicemails to return + * @return mixed decoded response payload + */ public function listVoicemails($page, $limit = 10) { $client = new Client(); @@ -43,6 +61,12 @@ public function listVoicemails($page, $limit = 10) { return $response->getData(); } + /** + * Fetch a single voicemail payload from the Yeaster microservice. + * + * @param int|string $id voicemail identifier + * @return string raw response content + */ public function viewVoicemail($id) { $client = new Client(); @@ -56,6 +80,12 @@ public function viewVoicemail($id) { return $response->content; } + /** + * Download a voicemail recording from the Yeaster microservice. + * + * @param int|string $id voicemail identifier + * @return string raw response content + */ public function downloadVoicemail($id) { $client = new Client(); From 81aed2515ebe6223ce96c2b03fa5fda6b856a6f7 Mon Sep 17 00:00:00 2001 From: Digz0 <172674408+digzrow-coder@users.noreply.github.com> Date: Sat, 16 May 2026 05:15:01 +0800 Subject: [PATCH 4/4] Trim service bearer tokens --- common/components/EventManager.php | 2 +- common/components/Yeaster.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/components/EventManager.php b/common/components/EventManager.php index 83c6abb20..eadac283a 100644 --- a/common/components/EventManager.php +++ b/common/components/EventManager.php @@ -425,7 +425,7 @@ public function call($method, $url, $data = []) { ->setFormat(Client::FORMAT_JSON) ->setData($data) ->addHeaders([ - 'Authorization' => 'Bearer ' . $this->sqsEndpointApiKey, + 'Authorization' => 'Bearer ' . trim((string) $this->sqsEndpointApiKey), "Content-Type" => "application/json", 'User-Agent' => 'request', ]) diff --git a/common/components/Yeaster.php b/common/components/Yeaster.php index 772f02743..696d72571 100644 --- a/common/components/Yeaster.php +++ b/common/components/Yeaster.php @@ -36,7 +36,7 @@ private function authorizationHeaders() } return [ - 'Authorization' => 'Bearer ' . $this->microserviceApiKey, + 'Authorization' => 'Bearer ' . trim((string) $this->microserviceApiKey), 'content-type' => 'application/json', ]; }