import json import unittest from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] CRM_PACK = REPO_ROOT / "salesforce-crm-standard" CONNECTED_APP_PATH = CRM_PACK / "connected_apps" / "salesforce_compat_client.json" AI_CONNECT_APP_PATH = CRM_PACK / "connected_apps" / "ai_assistant_connect.json" CODEX_CONNECT_APP_PATH = CRM_PACK / "connected_apps" / "codex_connect.json" CLAUDE_CODE_CONNECT_APP_PATH = CRM_PACK / "connected_apps" / "claude_code_connect.json" def load_json(path: Path): with path.open(encoding="utf-8") as handle: return json.load(handle) class ConnectedAppContractsTest(unittest.TestCase): def test_salesforce_compat_client_manifest_component_is_locked(self): manifest = load_json(CRM_PACK / "pack.json") components = { (component["kind"], component["businessKey"]): component for component in manifest["components"] } component = components[("connected_app", "salesforce-compat-client")] self.assertEqual(component["manageability"], "locked") self.assertEqual(component["path"], "connected_apps/salesforce_compat_client.json") self.assertNotIn("payload", component) def test_salesforce_compat_client_payload_owns_session_class(self): connected_app = load_json(CONNECTED_APP_PATH) self.assertEqual(connected_app["id"], "salesforce-compat-client") self.assertEqual(connected_app["name"], "Salesforce Compatibility Client") self.assertEqual(connected_app["consumerKey"], "salesforce-compat-client") self.assertEqual(connected_app["consumerSecret"], "salesforce-compat-internal") self.assertEqual(connected_app["consentVersion"], 1) self.assertEqual(connected_app["permittedUsers"], "AllUsers") self.assertEqual(connected_app["sessionIssuerClass"], "salesforce_compat") def test_ai_connect_manifest_component_is_locked_and_scope_ordered(self): manifest = load_json(CRM_PACK / "pack.json") components = { (component["kind"], component["businessKey"]): component for component in manifest["components"] } component = components[("connected_app", "nexuscrm-ai-connect")] self.assertEqual(component["manageability"], "locked") self.assertEqual(component["path"], "connected_apps/ai_assistant_connect.json") self.assertNotIn("payload", component) # The app grants external.records.read, so the scope must seed first. self.assertIn( {"kind": "oauth_custom_scope", "businessKey": "external.records.read"}, component.get("dependsOn", []), ) def test_ai_connect_payload_is_a_safe_public_pkce_client(self): connected_app = load_json(AI_CONNECT_APP_PATH) self.assertEqual(connected_app["id"], "nexuscrm-ai-connect") # consumerKey is the Client ID end users paste into their AI client's # connector settings — it is shared and NOT a secret, but it must stay # stable: changing it invalidates every published instruction. self.assertEqual(connected_app["consumerKey"], "nexuscrm-ai-connect") # Public PKCE client, fail-closed shape: no secret, no password or # refresh grant, no run-as user, no first-party session class, read-only # scope. Resource-bound MCP access tokens deliberately have no refresh # path, so this provisioned client must remain eligible for that flow. self.assertEqual(connected_app["clientType"], "public") self.assertNotIn("consumerSecret", connected_app) self.assertEqual(connected_app["tokenEndpointAuthMethod"], "none") self.assertIs(connected_app["requirePkce"], True) self.assertIs(connected_app["issueRefreshTokens"], False) self.assertEqual( connected_app["allowedGrantTypes"], ["authorization_code"], ) self.assertEqual(connected_app["scopes"], ["external.records.read"]) self.assertNotIn("runAsUserId", connected_app) self.assertNotIn("sessionIssuerClass", connected_app) # Redirects: exact HTTPS callbacks on Claude's hosts only. for uri in connected_app["redirectUris"]: self.assertTrue(uri.startswith("https://"), uri) self.assertEqual( connected_app["redirectUris"], [ "https://claude.ai/api/mcp/auth_callback", "https://claude.com/api/mcp/auth_callback", ], ) self.assertIn(connected_app["callbackUrl"], connected_app["redirectUris"]) self.assertIs(connected_app["isActive"], True) self.assertEqual(connected_app["consentPolicy"], "trusted") self.assertEqual(connected_app["consentVersion"], 1) self.assertEqual(connected_app["permittedUsers"], "AllUsers") def test_codex_connect_manifest_component_is_locked_and_scope_ordered(self): manifest = load_json(CRM_PACK / "pack.json") components = { (component["kind"], component["businessKey"]): component for component in manifest["components"] } component = components[("connected_app", "nexuscrm-codex-connect")] self.assertEqual(component["manageability"], "locked") self.assertEqual(component["path"], "connected_apps/codex_connect.json") self.assertNotIn("payload", component) self.assertIn( {"kind": "oauth_custom_scope", "businessKey": "external.records.read"}, component.get("dependsOn", []), ) def test_codex_connect_payload_is_a_safe_fixed_callback_pkce_client(self): connected_app = load_json(CODEX_CONNECT_APP_PATH) self.assertEqual(connected_app["id"], "nexuscrm-codex-connect") # This public Client ID is intentionally distinct from the Claude # client so a callback or revocation change cannot affect Claude. self.assertEqual(connected_app["consumerKey"], "nexuscrm-codex-connect") self.assertEqual(connected_app["clientType"], "public") self.assertNotIn("consumerSecret", connected_app) self.assertEqual(connected_app["tokenEndpointAuthMethod"], "none") self.assertIs(connected_app["requirePkce"], True) self.assertIs(connected_app["issueRefreshTokens"], False) self.assertEqual(connected_app["allowedGrantTypes"], ["authorization_code"]) self.assertEqual(connected_app["scopes"], ["external.records.read"]) self.assertNotIn("runAsUserId", connected_app) self.assertNotIn("sessionIssuerClass", connected_app) # Codex 0.142.3 derives a deterministic callback ID from the complete # MCP server URL when its callback port is fixed at 59152. Keep only the # exact callbacks derived from the supported Staging and Prod URLs; # broadening this to a wildcard or another client callback would weaken # redirect validation and conflate client identities. self.assertEqual( connected_app["redirectUris"], [ "http://127.0.0.1:59152/callback/l-qlK3CGE-2s", "http://127.0.0.1:59152/callback/KfqlwIpkH6lR", ], ) self.assertEqual( connected_app["callbackUrl"], "http://127.0.0.1:59152/callback/l-qlK3CGE-2s", ) self.assertIs(connected_app["isActive"], True) self.assertEqual(connected_app["consentPolicy"], "trusted") self.assertEqual(connected_app["consentVersion"], 1) self.assertEqual(connected_app["permittedUsers"], "AllUsers") def test_claude_code_connect_manifest_component_is_locked_and_scope_ordered(self): manifest = load_json(CRM_PACK / "pack.json") components = { (component["kind"], component["businessKey"]): component for component in manifest["components"] } component = components[("connected_app", "nexuscrm-claude-code-connect")] self.assertEqual(component["manageability"], "locked") self.assertEqual(component["path"], "connected_apps/claude_code_connect.json") self.assertNotIn("payload", component) self.assertIn( {"kind": "oauth_custom_scope", "businessKey": "external.records.read"}, component.get("dependsOn", []), ) def test_claude_code_connect_payload_is_a_safe_fixed_callback_pkce_client(self): connected_app = load_json(CLAUDE_CODE_CONNECT_APP_PATH) self.assertEqual(connected_app["id"], "nexuscrm-claude-code-connect") self.assertEqual(connected_app["consumerKey"], "nexuscrm-claude-code-connect") self.assertEqual(connected_app["clientType"], "public") self.assertNotIn("consumerSecret", connected_app) self.assertEqual(connected_app["tokenEndpointAuthMethod"], "none") # The existing public-client schema expresses the S256 PKCE policy as # requirePkce; this profile must not introduce a parallel field. self.assertIs(connected_app["requirePkce"], True) self.assertIs(connected_app["issueRefreshTokens"], False) self.assertEqual(connected_app["allowedGrantTypes"], ["authorization_code"]) self.assertEqual(connected_app["scopes"], ["external.records.read"]) self.assertNotIn("runAsUserId", connected_app) self.assertNotIn("sessionIssuerClass", connected_app) # Claude Code 2.1.221 uses a user-selected fixed callback port for an # administrator-pre-registered URI. Do not broaden this to a range, # reuse Codex, or reuse hosted-Claude callback identities. self.assertEqual( connected_app["redirectUris"], ["http://localhost:3118/callback"], ) self.assertEqual(connected_app["callbackUrl"], "http://localhost:3118/callback") self.assertIs(connected_app["isActive"], True) self.assertEqual(connected_app["consentPolicy"], "trusted") self.assertEqual(connected_app["consentVersion"], 1) self.assertEqual(connected_app["permittedUsers"], "AllUsers") if __name__ == "__main__": unittest.main()