diff --git a/lib/sdm.js b/lib/sdm.js index 10dffdee..c914958b 100644 --- a/lib/sdm.js +++ b/lib/sdm.js @@ -104,12 +104,20 @@ let subdomain = cds.context?.user?.authInfo?.token?.payload?.ext_attr?.zdn; } const userJwt = retrieveJwt(req); - const destination = await getDestinationFromServiceBinding({ + let destination; + if (!cds.context?.user?.authInfo?.token?.payload?.origin) { + let subdomain = cds.context?.user?.authInfo?.token?.payload?.ext_attr?.zdn; + destination = await getDestinationFromServiceBinding({ + destinationName: getSdmInstanceName(), + useCache: true, + serviceBindingTransformFn: (serviceBinding, options) => transformSDMServiceBindingToClientCredentialsDestination(serviceBinding, options, subdomain)}); + } else { + destination = await getDestinationFromServiceBinding({ destinationName: getSdmInstanceName(), jwt: userJwt, useCache: true, - serviceBindingTransformFn: (serviceBinding, options) => transformSDMServiceBindingToJWTBearerCredentialsDestination(serviceBinding, options, userJwt) - }); + serviceBindingTransformFn: (serviceBinding, options) => transformSDMServiceBindingToJWTBearerCredentialsDestination(serviceBinding, options, userJwt)}); + } // Cache for subsequent calls in the same request req._sdmDestination = destination; diff --git a/test/lib/sdm.test.js b/test/lib/sdm.test.js index 0a38e2f7..c08764d3 100644 --- a/test/lib/sdm.test.js +++ b/test/lib/sdm.test.js @@ -442,6 +442,22 @@ describe("SDMAttachmentsService", () => { _sdmDestination: undefined }; + // Mock cds.context with origin to trigger JWT Bearer flow + cds.context = { + user: { + authInfo: { + token: { + payload: { + origin: "sap.custom", + ext_attr: { + zdn: "test-subdomain" + } + } + } + } + } + }; + retrieveJwt.mockReturnValue("user-jwt"); getSdmInstanceName.mockReturnValue("sdm-instance"); const mockDestination = { url: "http://example.com" }; @@ -473,6 +489,87 @@ describe("SDMAttachmentsService", () => { expect(getDestinationFromServiceBinding).not.toHaveBeenCalled(); expect(result).toEqual(cachedDestination); }); + + it("should use Client Credentials when origin is not present in token", async () => { + jest.clearAllMocks(); + const service = new SDMAttachmentsService(); + const mockReq = { + _sdmDestination: undefined + }; + + // Mock cds.context without origin in token payload + cds.context = { + user: { + authInfo: { + token: { + payload: { + ext_attr: { + zdn: "test-subdomain" + } + // No 'origin' field here + } + } + } + } + }; + + retrieveJwt.mockReturnValue("user-jwt"); + getSdmInstanceName.mockReturnValue("sdm-instance"); + const mockDestination = { url: "http://example.com" }; + getDestinationFromServiceBinding.mockResolvedValue(mockDestination); + + const result = await service.getDestination(mockReq); + + // Should call with Client Credentials (no jwt parameter) + expect(getDestinationFromServiceBinding).toHaveBeenCalledWith({ + destinationName: "sdm-instance", + useCache: true, + serviceBindingTransformFn: expect.any(Function) + }); + expect(result).toEqual(mockDestination); + expect(mockReq._sdmDestination).toEqual(mockDestination); + }); + + it("should use JWT Bearer when origin is present in token", async () => { + jest.clearAllMocks(); + const service = new SDMAttachmentsService(); + const mockReq = { + _sdmDestination: undefined + }; + + // Mock cds.context with origin in token payload + cds.context = { + user: { + authInfo: { + token: { + payload: { + origin: "sap.custom", + ext_attr: { + zdn: "test-subdomain" + } + } + } + } + } + }; + + retrieveJwt.mockReturnValue("user-jwt"); + getSdmInstanceName.mockReturnValue("sdm-instance"); + const mockDestination = { url: "http://example.com" }; + getDestinationFromServiceBinding.mockResolvedValue(mockDestination); + + const result = await service.getDestination(mockReq); + + // Should call with JWT Bearer (includes jwt parameter) + expect(getDestinationFromServiceBinding).toHaveBeenCalledWith({ + destinationName: "sdm-instance", + jwt: "user-jwt", + useCache: true, + serviceBindingTransformFn: expect.any(Function) + }); + expect(result).toEqual(mockDestination); + expect(mockReq._sdmDestination).toEqual(mockDestination); + }); }); describe("getSDMCredentials", () => {