diff --git a/cli/commands/component/init/openapi/src/main/java/com/bytechef/cli/command/component/init/openapi/ComponentInitOpenApiGenerator.java b/cli/commands/component/init/openapi/src/main/java/com/bytechef/cli/command/component/init/openapi/ComponentInitOpenApiGenerator.java index 2699be5642a..83fc6d4a69e 100644 --- a/cli/commands/component/init/openapi/src/main/java/com/bytechef/cli/command/component/init/openapi/ComponentInitOpenApiGenerator.java +++ b/cli/commands/component/init/openapi/src/main/java/com/bytechef/cli/command/component/init/openapi/ComponentInitOpenApiGenerator.java @@ -26,6 +26,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; @@ -90,6 +91,7 @@ import javax.tools.JavaCompiler; import javax.tools.ToolProvider; import org.apache.commons.lang3.StringUtils; +import org.jspecify.annotations.NonNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -394,6 +396,15 @@ private void checkAdditionalProperties( if (schema.getExample() != null) { if (Objects.equals(type, "string")) { builder.add(".exampleValue($S)", schema.getExample()); + } else if (Objects.equals(type, "array")) { + ArrayNode exampleArrayNode = (ArrayNode) schema.getExample(); + Object[] exampleArray = new Object[exampleArrayNode.size()]; + + for (int i = 0; i < exampleArray.length; i++) { + exampleArray[i] = exampleArrayNode.get(i); + } + + builder.add(".exampleValue($L)", exampleArray); } else { builder.add(".exampleValue($L)", schema.getExample()); } @@ -1605,31 +1616,29 @@ private String getPackageName() { } private CodeBlock getParametersPropertiesCodeBlock(Operation operation, OpenAPI openAPI) { + List parameters = resolveParameters(operation.getParameters(), openAPI); List codeBlocks = new ArrayList<>(); - List parameters = operation.getParameters(); - if (parameters != null) { - for (Parameter parameter : parameters) { - CodeBlock.Builder builder = CodeBlock.builder(); + for (Parameter parameter : parameters) { + CodeBlock.Builder builder = CodeBlock.builder(); - builder.add( - getSchemaCodeBlock( - parameter.getName(), parameter.getDescription(), parameter.getRequired(), null, - parameter.getSchema(), false, false, openAPI, false)); - builder.add( - CodeBlock.of( - """ - .metadata( - $T.of( - "type", PropertyType.$L - ) - ) - """, - Map.class, - StringUtils.upperCase(parameter.getIn()))); - - codeBlocks.add(builder.build()); - } + builder.add( + getSchemaCodeBlock( + parameter.getName(), parameter.getDescription(), parameter.getRequired(), null, + parameter.getSchema(), false, false, openAPI, false)); + builder.add( + CodeBlock.of( + """ + .metadata( + $T.of( + "type", PropertyType.$L + ) + ) + """, + Map.class, + StringUtils.upperCase(parameter.getIn()))); + + codeBlocks.add(builder.build()); } return codeBlocks.stream() @@ -1736,6 +1745,55 @@ private CodeBlock getRefCodeBlock( outputSchema, openAPI, bodySchema); } + private List resolveParameters(List parameters, OpenAPI openAPI) { + if (parameters == null) { + return Collections.emptyList(); + } + + List resolvedParameters = new ArrayList<>(); + + parameters.forEach(explicitParameter -> { + if (explicitParameter.get$ref() == null) { + resolvedParameters.add(explicitParameter); + + return; + } + + resolvedParameters.add(getComponentParameter(openAPI, explicitParameter)); + }); + + return resolvedParameters; + } + + private static @NonNull Parameter getComponentParameter(OpenAPI openAPI, Parameter explicitParameter) { + Components components = openAPI.getComponents(); + + if (components == null) { + throw new IllegalArgumentException( + "Components section of spec misses. Unable to resolve " + explicitParameter.get$ref()); + } + + Map parameterDefinitions = components.getParameters(); + String parameterName = getParameterNameFromComponentReference(explicitParameter); + + if ((parameterDefinitions == null) || !parameterDefinitions.containsKey(parameterName)) { + throw new IllegalArgumentException( + "Components section of spec misses the parameter definition for " + explicitParameter.get$ref()); + } + + return parameterDefinitions.get(parameterName); + } + + private static String getParameterNameFromComponentReference(Parameter parameter) { + String parameterReference = parameter.get$ref(); + + if (parameterReference.startsWith("#/components/parameters/")) { + parameterReference = parameterReference.substring("#/components/parameters/".length()); + } + + return parameterReference; + } + @SuppressWarnings({ "rawtypes" }) diff --git a/docs/content/docs/developer-guide/generate-component/initial-setup.mdx b/docs/content/docs/developer-guide/generate-component/initial-setup.mdx index 169b0b27038..b8f03dc98d8 100644 --- a/docs/content/docs/developer-guide/generate-component/initial-setup.mdx +++ b/docs/content/docs/developer-guide/generate-component/initial-setup.mdx @@ -7,7 +7,7 @@ title: "Initial Setup" This section provides a clear step-by-step guide for setting up a new component in your project, ensuring it is properly integrated into the build system and recognized by the IDE. 1. Create a New Package: - - Navigate to `server/apps/libs/modules/components/`. + - Navigate to `server/libs/modules/components/`. - Create a new package with the name of your component, e.g., `newcomponent`. 2. Update Settings: diff --git a/sdks/backend/java/component-api/src/main/java/com/bytechef/component/definition/ActionContext.java b/sdks/backend/java/component-api/src/main/java/com/bytechef/component/definition/ActionContext.java index 0dcfdaa842a..5715b353469 100644 --- a/sdks/backend/java/component-api/src/main/java/com/bytechef/component/definition/ActionContext.java +++ b/sdks/backend/java/component-api/src/main/java/com/bytechef/component/definition/ActionContext.java @@ -28,6 +28,13 @@ */ public interface ActionContext extends Context { + /** + * Returns trace id which originates from micro meter + * + * @return traceId + */ + String getTraceId(); + /** * @param approvalFunction */ diff --git a/sdks/backend/java/component-api/src/main/java/com/bytechef/component/definition/ComponentDsl.java b/sdks/backend/java/component-api/src/main/java/com/bytechef/component/definition/ComponentDsl.java index cee3603b918..8c42f4d8e50 100644 --- a/sdks/backend/java/component-api/src/main/java/com/bytechef/component/definition/ComponentDsl.java +++ b/sdks/backend/java/component-api/src/main/java/com/bytechef/component/definition/ComponentDsl.java @@ -4106,6 +4106,11 @@ public void suspend(Suspend suspend) { throw new UnsupportedOperationException(); } + @Override + public String getTraceId() { + throw new UnsupportedOperationException(); + } + @Override public R xml(ContextFunction xmlFunction) { return context.xml(xmlFunction); diff --git a/server/libs/modules/components/ai/agent/src/main/java/com/bytechef/component/ai/agent/tool/AiAgentChatTool.java b/server/libs/modules/components/ai/agent/src/main/java/com/bytechef/component/ai/agent/tool/AiAgentChatTool.java index 7687156eaf0..dd0f3e5f1b3 100644 --- a/server/libs/modules/components/ai/agent/src/main/java/com/bytechef/component/ai/agent/tool/AiAgentChatTool.java +++ b/server/libs/modules/components/ai/agent/src/main/java/com/bytechef/component/ai/agent/tool/AiAgentChatTool.java @@ -153,6 +153,11 @@ public void suspend(Suspend suspend) { throw new UnsupportedOperationException(); } + @Override + public String getTraceId() { + throw new UnsupportedOperationException(); + } + @Override public R xml(ContextFunction xmlFunction) { return context.xml(xmlFunction); diff --git a/server/libs/modules/components/ftp/src/test/java/com/bytechef/component/ftp/action/BaseFtpActionIntTest.java b/server/libs/modules/components/ftp/src/test/java/com/bytechef/component/ftp/action/BaseFtpActionIntTest.java index 52834d8251c..51cc22dbb61 100644 --- a/server/libs/modules/components/ftp/src/test/java/com/bytechef/component/ftp/action/BaseFtpActionIntTest.java +++ b/server/libs/modules/components/ftp/src/test/java/com/bytechef/component/ftp/action/BaseFtpActionIntTest.java @@ -120,6 +120,11 @@ public R outputSchema(ContextFunction outputSchemaFunction) throw new UnsupportedOperationException("Disabled in test mode"); } + @Override + public String getTraceId() { + throw new UnsupportedOperationException("Disabled in test mode"); + } + @Override public R xml(ContextFunction xmlFunction) { throw new UnsupportedOperationException("Disabled in test mode"); diff --git a/server/libs/modules/components/gaurus/build.gradle b/server/libs/modules/components/gaurus/build.gradle new file mode 100644 index 00000000000..190b578b89f --- /dev/null +++ b/server/libs/modules/components/gaurus/build.gradle @@ -0,0 +1 @@ +version="1.0" diff --git a/server/libs/modules/components/gaurus/gaurusOpenApi.yaml b/server/libs/modules/components/gaurus/gaurusOpenApi.yaml new file mode 100644 index 00000000000..782b5b5a1b1 --- /dev/null +++ b/server/libs/modules/components/gaurus/gaurusOpenApi.yaml @@ -0,0 +1,540 @@ +openapi: "3.0.0" +info: + title: "Bank Connect" + version: "1.0.0" + description: "Bank Connect API specification" + contact: + email: "psd2@gaurus.hr" +servers: + - url: https://bankconnect.gaurus.hr/api/client +paths: + /accounts: + get: + tags: + - "Accounts" + operationId: getAccounts + summary: "Gets accounts for provided client id." + parameters: + - $ref: "#/components/parameters/ClientId" + - $ref: "#/components/parameters/RequestId" + - $ref: "#/components/parameters/Timestamp" + - $ref: "#/components/parameters/Signature" + responses: + "200": + description: "Success." + content: + application/json: + schema: + $ref: "#/components/schemas/MyResponse" + example: + code: "OK" + message: "" + hasMoreResults: false + data: "AccountResult[]" + "500": + $ref: "#/components/responses/InternalServerError" + /accounts/{iban}/transactions: + get: + tags: + - "Accounts" + operationId: getAccountTransactions + summary: "Gets transactions for provided IBAN and query parameters." + description: "General rules for query parameters: +
    +
  • If lastTransactionid is provided without date parameters system will not set default values for date range (only lastTransactionId will be used for data filtering).
  • +
  • Max range between dateFrom and dateTo is 7 days. If provided date range is greater, dateFrom is set to the dateTo minus 7 days.
  • +
  • If dateFrom and dateTo are not provided: +
      +
    • dateFrom is set to the current date minus 7 days
    • +
    • dateTo is set to the current date
    • +
    +
  • +
  • If dateFrom is provided and dateTo is not provided: +
      +
    1. If dateFrom is set to future date, it is set to the current date.
    2. +
    3. dateTo is set to dateFrom plus 1 day
    4. +
    +
  • +
  • If dateFrom is not provided and dateTo is provided: +
      +
    1. If dateTo is set to future date, it is set to the current date.
    2. +
    3. dateFrom is set to dateTo minus 1 day
    4. +
    +
  • +
" + parameters: + - $ref: "#/components/parameters/ClientId" + - $ref: "#/components/parameters/RequestId" + - $ref: "#/components/parameters/Timestamp" + - $ref: "#/components/parameters/Signature" + - in: path + name: iban + description: "Account IBAN." + required: true + schema: + type: string + example: "HR1210010051863000160" + - in: query + name: dateFrom + description: "Oldest transaction execution date." + required: false + schema: + type: string + example: "2021-01-01" + - in: query + name: dateTo + description: "Newest transaction execution date." + required: false + schema: + type: string + example: "2021-01-01" + - in: query + name: lastTransactionId + description: "If this parameter is specified, system will return transactions stored after the corresponding transaction." + required: false + schema: + type: integer + example: 123 + responses: + "200": + description: "Success." + content: + application/json: + schema: + $ref: "#/components/schemas/MyResponse" + example: + code: "OK" + message: "" + hasMoreResults: true + data: "TransactionResult[]" + "400": + description: "Validation failed." + content: + application/json: + schema: + $ref: "#/components/schemas/MyResponse" + example: + code: "VALIDATION_FAILED" + message: "Iban valid: false" + hasMoreResults: false + data: "[]" + "500": + $ref: "#/components/responses/InternalServerError" + /external-users: + get: + tags: + - "External Users" + operationId: getExternalUsers + summary: "Gets external users for provided client id." + parameters: + - $ref: "#/components/parameters/ClientId" + - $ref: "#/components/parameters/RequestId" + - $ref: "#/components/parameters/Timestamp" + - $ref: "#/components/parameters/Signature" + responses: + "200": + description: "Success." + content: + application/json: + schema: + $ref: "#/components/schemas/ServiceResponse" + example: + data: + - id: 42 + name: "Pero Perić d.o.o." + oib: "12345678901" + mail: "pero@example.com" + bankEntries: + - bankSlug: "erste" + ibans: ["HR1210010051863000160"] + consentJobStatus: "PENDING" + errors: [] + "500": + $ref: "#/components/responses/InternalServerError" + post: + tags: + - "External Users" + operationId: postExternalUsers + summary: "Creates external users with bank consent jobs." + parameters: + - $ref: "#/components/parameters/ClientId" + - $ref: "#/components/parameters/RequestId" + - $ref: "#/components/parameters/Timestamp" + - $ref: "#/components/parameters/Signature" + requestBody: + required: true + content: + application/json: + schema: + type: "array" + items: + $ref: "#/components/schemas/ExternalUserRequest" + example: + - name: "Pero Perić d.o.o." + oib: "12345678901" + mail: "pero@example.com" + bankEntries: + - bankSlug: "erste" + ibans: ["HR1210010051863000160"] + psuIdType: "HRIdentificationNumber" + responses: + "200": + description: "Success." + content: + application/json: + schema: + $ref: "#/components/schemas/ServiceResponse" + example: + data: + - existingMails: ["existing@example.com"] + newMails: ["new@example.com"] + errors: [] + "500": + $ref: "#/components/responses/InternalServerError" + /external-users/{externalUserId}: + put: + tags: + - "External Users" + operationId: putExternalUser + summary: "Updates an external user." + parameters: + - $ref: "#/components/parameters/ClientId" + - $ref: "#/components/parameters/RequestId" + - $ref: "#/components/parameters/Timestamp" + - $ref: "#/components/parameters/Signature" + - in: path + name: externalUserId + description: "External user identifier." + required: true + schema: + type: integer + format: int64 + example: 42 + responses: + "200": + description: "Success." + "500": + $ref: "#/components/responses/InternalServerError" + delete: + tags: + - "External Users" + operationId: deleteExternalUser + summary: "Deletes an external user." + parameters: + - $ref: "#/components/parameters/ClientId" + - $ref: "#/components/parameters/RequestId" + - $ref: "#/components/parameters/Timestamp" + - $ref: "#/components/parameters/Signature" + - in: path + name: externalUserId + description: "External user identifier." + required: true + schema: + type: integer + format: int64 + example: 42 + responses: + "204": + description: "External user deleted successfully." + "500": + $ref: "#/components/responses/InternalServerError" +components: + parameters: + ClientId: + in: header + name: clientId + description: "Client identifier provided by the system." + required: true + schema: + type: string + format: uuid + example: "4181a492-97bf-48ee-b29e-d7d6860c5565" + RequestId: + in: header + name: requestId + description: "Unique identifier of a request (must be generated by client)." + required: true + schema: + type: string + format: uuid + example: "17fcaa13-eb6d-467c-a757-2e669179a19e" + Timestamp: + in: header + name: timestamp + description: "Current timestamp in UTC format (must be generated by client)." + required: true + schema: + type: string + format: date-time + example: "2021-01-01T11:38:20.791Z" + Signature: + in: header + name: signature + description: " +

Request signature calculated by client. Algorithm for signing is as follows:

+
    +
  1. + Prepare payload for signing: {clientId};{requestId};{timestamp};{uri};{body} +
      +
    • + Uri example: For full URL https://example.com/MyProject/api/accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02, {uri} value used for calculation is /accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02. Note that leading slash and all query parameters must be included! +
    • +
    • + If request body is not present, use empty string for {body} value. +
    • +
    +
  2. +
  3. Using client secret sign the payload with HmacSHA256 algorithm.
  4. +
  5. Encode resulting signature in base64.
  6. +
" + required: true + schema: + type: string + example: "ybHjifCXXHlDNNfY8sOIK9BRoTHlxXYjusUaoN5SCp4=" + schemas: + ServiceResponse: + type: "object" + description: "Standard response wrapper for all API endpoints." + properties: + data: + type: "array" + items: + oneOf: + - $ref: "#/components/schemas/ExternalUserResult" + - $ref: "#/components/schemas/CreateExternalUsersResponse" + description: "List of results (empty if the response is not valid)." + errors: + type: "array" + items: + $ref: "#/components/schemas/ErrorData" + description: "List of errors (empty if the response is valid)." + ErrorData: + type: "object" + properties: + code: + type: "string" + description: "Error code." + example: "GENERAL_ERROR" + description: + type: "string" + description: "Error description." + example: "General error" + AccountResult: + type: "object" + properties: + companyName: + type: "string" + description: "Account owner. This field is NOT present for the REGULAR users." + example: "Gaurus d.o.o." + iban: + type: "string" + description: "Account IBAN." + example: "HR1210010051863000160" + accountName: + type: "string" + description: "Account name." + example: "Tekući račun" + bankName: + type: "string" + description: "Bank name." + example: "Erste bank" + ExternalUserResult: + type: "object" + properties: + id: + type: "integer" + format: "int64" + description: "External user identifier." + example: 42 + name: + type: "string" + description: "External user company name." + example: "Pero Perić d.o.o." + oib: + type: "string" + description: "External user OIB (Croatian personal identification number)." + example: "12345678901" + mail: + type: "string" + description: "External user email address." + example: "pero@example.com" + bankEntries: + type: "array" + items: + $ref: "#/components/schemas/BankEntry" + description: "List of bank entries with consent status." + ExternalUserRequest: + type: "object" + properties: + name: + type: "string" + description: "External user company name." + example: "Pero Perić d.o.o." + oib: + type: "string" + description: "External user OIB (Croatian personal identification number)." + example: "12345678901" + mail: + type: "string" + description: "External user email address." + example: "pero@example.com" + bankEntries: + type: "array" + items: + $ref: "#/components/schemas/BankEntryRequest" + description: "List of bank entries to create consent jobs for." + BankEntry: + type: "object" + properties: + bankSlug: + type: "string" + description: "Bank identifier slug." + example: "erste" + ibans: + type: "array" + items: + type: "string" + description: "List of IBANs." + example: ["HR1210010051863000160"] + consentJobStatus: + type: "string" + format: "enum" + enum: ["SUCCESS", "FAILED", "PENDING"] + description: "Status of the consent job for this bank entry." + example: "PENDING" + BankEntryRequest: + type: "object" + properties: + bankSlug: + type: "string" + description: "Bank identifier slug." + example: "erste" + ibans: + type: "array" + items: + type: "string" + description: "List of IBANs." + example: ["HR1210010051863000160"] + psuIdType: + type: "string" + description: "PSU ID type for the bank consent." + example: "HRIdentificationNumber" + CreateExternalUsersResponse: + type: "object" + properties: + existingMails: + type: "array" + items: + type: "string" + description: "Email addresses that already exist in the system." + example: ["existing@example.com"] + newMails: + type: "array" + items: + type: "string" + description: "Email addresses of newly created external users." + example: ["new@example.com"] + MyResponse: + type: "object" + properties: + code: + $ref: "#/components/schemas/MyResponseCode" + message: + type: "string" + description: "The error message, present only if the \"code\" property is not \"OK\"." + example: "General error" + hasMoreResults: + type: "boolean" + description: "System limits number of transactions in response. If there are more results related to the request, this flag is set to true. In that case client should initiate a new request with the value of lastTransactionId parameter set to the greatest received transaction identifier plus 1." + example: true + data: + type: "array" + items: + oneOf: + - $ref: "#/components/schemas/AccountResult" + - $ref: "#/components/schemas/TransactionResult" + description: "List of objects related to the request." + MyResponseCode: + type: "string" + format: "enum" + enum: ["OK", "VALIDATION_FAILED", "DATA_UNAVAILABLE", "CONSENT_EXPIRED", "GENERAL_ERROR"] + description: "Represents resulting code in case when the system has handled a request." + TransactionResult: + type: "object" + properties: + id: + type: "integer" + description: "Transaction identifier from our system." + example: "123" + bankResourceId: + type: "integer" + description: "Transaction identifier from the bank." + example: "TID1234567890" + senderName: + type: "string" + description: "Sender name." + example: "Pero Perić" + senderIban: + type: "string" + description: "Sender IBAN." + example: "HR1210010051863000160" + receiverName: + type: "string" + description: "Receiver name." + example: "Miro Mirić" + receiverIban: + type: "string" + description: "Receiver IBAN." + example: "HR1210010051863000160" + amount: + type: "string" + description: "Transaction amount." + example: "123.45" + currency: + type: "string" + description: "Transaction currency." + example: "HRK" + paymentOrderExecutionDate: + type: "string" + description: "Date of the payment." + example: "2021-01-02" + description: + type: "string" + description: "Transaction description." + example: "Kupovina na POS-u Konzum Ravnice" + remittanceInformationStructured: + type: "string" + description: "Remitance information about the transaction separated by semicolon." + example: "HR99;HRXXXXXX-YYYY-ZZZZ;" + additionalInformation: + type: "string" + description: "Some additional information about the transaction separated by semicolon that isn't included in the original description, e.g. creditor or debtor address etc." + example: "creditorAddress:JURIŠIĆEVA 4, ZAGREB;debtorAddress:HRAŠĆANSKA 13, ZAGREB" + endToEndId: + type: "string" + description: "SEPA End-To-End-ID." + example: "HR99" + purposeCode: + type: "string" + description: "Transaction purpose code." + example: "WTER" + ultimateCreditor: + type: "string" + description: "Ultimate creditor name." + example: "Pero Perić" + ultimateDebtor: + type: "string" + description: "Ultimate debtor name." + example: "Miro Mirić" + responses: + InternalServerError: + description: "Internal server error." + content: + application/json: + schema: + $ref: "#/components/schemas/MyResponse" + example: + code: "GENERAL_ERROR" + message: "General error" + hasMoreResults: false + data: [] diff --git a/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/AbstractGaurusComponentHandler.java b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/AbstractGaurusComponentHandler.java new file mode 100644 index 00000000000..4ab40518c7c --- /dev/null +++ b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/AbstractGaurusComponentHandler.java @@ -0,0 +1,55 @@ +/* + * Copyright 2025 ByteChef + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bytechef.component.gaurus; + +import static com.bytechef.component.definition.ComponentDsl.component; + +import com.bytechef.component.OpenApiComponentHandler; +import com.bytechef.component.definition.ComponentDefinition; +import com.bytechef.component.gaurus.action.GaurusDeleteExternalUserAction; +import com.bytechef.component.gaurus.action.GaurusGetAccountTransactionsAction; +import com.bytechef.component.gaurus.action.GaurusGetAccountsAction; +import com.bytechef.component.gaurus.action.GaurusGetExternalUsersAction; +import com.bytechef.component.gaurus.action.GaurusPostExternalUsersAction; +import com.bytechef.component.gaurus.action.GaurusPutExternalUserAction; +import com.bytechef.component.gaurus.connection.GaurusConnection; + +/** + * Provides the base implementation for the REST based component. + * + * @generated + * + * @author Igor Beslic + */ +public abstract class AbstractGaurusComponentHandler implements OpenApiComponentHandler { + private final ComponentDefinition componentDefinition = modifyComponent( + component("gaurus") + .title("Bank Connect") + .description("Bank Connect API specification") + .version(1)) + .actions(modifyActions(GaurusDeleteExternalUserAction.ACTION_DEFINITION, + GaurusGetAccountsAction.ACTION_DEFINITION, GaurusGetAccountTransactionsAction.ACTION_DEFINITION, + GaurusGetExternalUsersAction.ACTION_DEFINITION, GaurusPostExternalUsersAction.ACTION_DEFINITION, + GaurusPutExternalUserAction.ACTION_DEFINITION)) + .connection(modifyConnection(GaurusConnection.CONNECTION_DEFINITION)) + .triggers(getTriggers()); + + @Override + public ComponentDefinition getDefinition() { + return componentDefinition; + } +} diff --git a/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/GaurusComponentHandler.java b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/GaurusComponentHandler.java new file mode 100644 index 00000000000..2b3dc56e364 --- /dev/null +++ b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/GaurusComponentHandler.java @@ -0,0 +1,124 @@ +/* + * Copyright 2025 ByteChef + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bytechef.component.gaurus; + +import com.bytechef.component.OpenApiComponentHandler; +import com.bytechef.component.definition.ActionContext; +import com.bytechef.component.definition.ActionDefinition; +import com.bytechef.component.definition.ComponentDsl; +import com.bytechef.component.definition.Context; +import com.bytechef.component.definition.Parameters; +import com.google.auto.service.AutoService; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.time.Instant; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.Base64; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +/** + * This class will not be overwritten on the repeated calls of the generator. + * + * @author Igor Beslic + */ +@AutoService(OpenApiComponentHandler.class) +public class GaurusComponentHandler extends AbstractGaurusComponentHandler { + + private static final String EMPTY_BODY = ""; + + public ComponentDsl.ModifiableActionDefinition + modifyAction(ComponentDsl.ModifiableActionDefinition modifiableActionDefinition) { + + Optional> metadata = modifiableActionDefinition.getMetadata(); + + Map metadataMap = metadata.orElseGet(Collections::emptyMap); + + String path = (String) metadataMap.get("path"); + + modifiableActionDefinition.perform(new ActionDefinition.PerformFunction() { + @Override + public Object apply(Parameters inputParameters, Parameters connectionParameters, ActionContext context) + throws Exception { + String endpoint = + connectionParameters.getRequiredString("baseUri") + path; + + Context.Http.Executor httpExecutor = context.http(http -> http.get(endpoint)); + + String clientId = connectionParameters.getString("clientId"); + String clientSecret = connectionParameters.getString("clientSecret"); + String requestId = asUuid(context.getTraceId()); + String timestamp = DateTimeFormatter.ISO_INSTANT.format(Instant.now() + .truncatedTo(ChronoUnit.MILLIS)); + + String body = EMPTY_BODY; + String signature = getSignature(clientId, clientSecret, requestId, timestamp, path, body, context); + + context.log(log -> log.debug( + "Executing endpoint: {} with clientId: {}, requestId: {}, timestamp: {}, uri: {}, body: {}, signature {}", + endpoint, clientId, requestId, timestamp, path, body, signature)); + + Context.Http.Response response = httpExecutor + .configuration(Context.Http + .allowUnauthorizedCerts(connectionParameters.getBoolean("allowSelfSignedCert", false))) + .headers(Map.of("clientId", List.of(clientId), "requestId", + List.of(requestId), "timestamp", List.of(timestamp), + "signature", List.of(signature))) + .execute(); + + return response.getBody(); + } + }); + + return modifiableActionDefinition; + } + + private static String getSignature( + String clientId, String clientSecret, String requestId, String timestamp, String uri, String body, + ActionContext context) { + + String forSigning = String.format("%s;%s;%s;%s;%s", clientId, requestId, timestamp, uri, body); + + context.log(log -> log.debug("Signing {} with {}", forSigning, clientSecret)); + + try { + Mac mac = Mac.getInstance("HmacSHA256"); + + mac.init(new SecretKeySpec(clientSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256")); + + return Base64.getEncoder() + .encodeToString(mac.doFinal(forSigning.getBytes(StandardCharsets.UTF_8))); + } catch (InvalidKeyException | NoSuchAlgorithmException exception) { + throw new RuntimeException("Failed to compute HmacSHA256 signature", exception); + } + } + + private static String asUuid(String rawUuid) { + if (rawUuid.contains("-")) { + return rawUuid; + } + + return rawUuid.replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5"); + } + +} diff --git a/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusDeleteExternalUserAction.java b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusDeleteExternalUserAction.java new file mode 100644 index 00000000000..20b11a7c9d3 --- /dev/null +++ b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusDeleteExternalUserAction.java @@ -0,0 +1,83 @@ +/* + * Copyright 2025 ByteChef + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bytechef.component.gaurus.action; + +import static com.bytechef.component.OpenApiComponentHandler.PropertyType; +import static com.bytechef.component.definition.ComponentDsl.action; +import static com.bytechef.component.definition.ComponentDsl.dateTime; +import static com.bytechef.component.definition.ComponentDsl.integer; +import static com.bytechef.component.definition.ComponentDsl.string; + +import com.bytechef.component.definition.ComponentDsl; +import java.util.Map; + +/** + * Provides a list of the component actions. + * + * @generated + * + * @author Igor Beslic + */ +public class GaurusDeleteExternalUserAction { + public static final ComponentDsl.ModifiableActionDefinition ACTION_DEFINITION = action("deleteExternalUser") + .title("Deletes an external user.") + .description(null) + .metadata( + Map.of( + "method", "DELETE", + "path", "/external-users/{externalUserId}" + + )) + .properties(string("clientId").label("Client Id") + .description("Client identifier provided by the system.") + .required(true) + .exampleValue("4181a492-97bf-48ee-b29e-d7d6860c5565") + .metadata( + Map.of( + "type", PropertyType.HEADER)), + string("requestId").label("Request Id") + .description("Unique identifier of a request (must be generated by client).") + .required(true) + .exampleValue("17fcaa13-eb6d-467c-a757-2e669179a19e") + .metadata( + Map.of( + "type", PropertyType.HEADER)), + dateTime("timestamp").label("Timestamp") + .description("Current timestamp in UTC format (must be generated by client).") + .required(true) + .metadata( + Map.of( + "type", PropertyType.HEADER)), + string("signature").label("Signature") + .description( + "

Request signature calculated by client. Algorithm for signing is as follows:

  1. Prepare payload for signing: {clientId};{requestId};{timestamp};{uri};{body}
    • Uri example: For full URL https://example.com/MyProject/api/accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02, {uri} value used for calculation is /accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02. Note that leading slash and all query parameters must be included!
    • If request body is not present, use empty string for {body} value.
  2. Using client secret sign the payload with HmacSHA256 algorithm.
  3. Encode resulting signature in base64.
") + .required(true) + .exampleValue("ybHjifCXXHlDNNfY8sOIK9BRoTHlxXYjusUaoN5SCp4=") + .metadata( + Map.of( + "type", PropertyType.HEADER)), + integer("externalUserId").label("External User Id") + .description("External user identifier.") + .required(true) + .exampleValue(42) + .metadata( + Map.of( + "type", PropertyType.PATH))); + + private GaurusDeleteExternalUserAction() { + } +} diff --git a/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusGetAccountTransactionsAction.java b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusGetAccountTransactionsAction.java new file mode 100644 index 00000000000..8ffe7237758 --- /dev/null +++ b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusGetAccountTransactionsAction.java @@ -0,0 +1,117 @@ +/* + * Copyright 2025 ByteChef + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bytechef.component.gaurus.action; + +import static com.bytechef.component.OpenApiComponentHandler.PropertyType; +import static com.bytechef.component.definition.ComponentDsl.action; +import static com.bytechef.component.definition.ComponentDsl.dateTime; +import static com.bytechef.component.definition.ComponentDsl.integer; +import static com.bytechef.component.definition.ComponentDsl.object; +import static com.bytechef.component.definition.ComponentDsl.outputSchema; +import static com.bytechef.component.definition.ComponentDsl.sampleOutput; +import static com.bytechef.component.definition.ComponentDsl.string; +import static com.bytechef.component.definition.Context.Http.ResponseType; + +import com.bytechef.component.definition.ComponentDsl; +import com.bytechef.component.gaurus.property.GaurusMyResponseProperties; +import java.util.Map; + +/** + * Provides a list of the component actions. + * + * @generated + * + * @author Igor Beslic + */ +public class GaurusGetAccountTransactionsAction { + public static final ComponentDsl.ModifiableActionDefinition ACTION_DEFINITION = action("getAccountTransactions") + .title("Gets transactions for provided IBAN and query parameters.") + .description( + "General rules for query parameters:
  • If lastTransactionid is provided without date parameters system will not set default values for date range (only lastTransactionId will be used for data filtering).
  • Max range between dateFrom and dateTo is 7 days. If provided date range is greater, dateFrom is set to the dateTo minus 7 days.
  • If dateFrom and dateTo are not provided:
    • dateFrom is set to the current date minus 7 days
    • dateTo is set to the current date
  • If dateFrom is provided and dateTo is not provided:
    1. If dateFrom is set to future date, it is set to the current date.
    2. dateTo is set to dateFrom plus 1 day
  • If dateFrom is not provided and dateTo is provided:
    1. If dateTo is set to future date, it is set to the current date.
    2. dateFrom is set to dateTo minus 1 day
") + .metadata( + Map.of( + "method", "GET", + "path", "/accounts/{iban}/transactions" + + )) + .properties(string("clientId").label("Client Id") + .description("Client identifier provided by the system.") + .required(true) + .exampleValue("4181a492-97bf-48ee-b29e-d7d6860c5565") + .metadata( + Map.of( + "type", PropertyType.HEADER)), + string("requestId").label("Request Id") + .description("Unique identifier of a request (must be generated by client).") + .required(true) + .exampleValue("17fcaa13-eb6d-467c-a757-2e669179a19e") + .metadata( + Map.of( + "type", PropertyType.HEADER)), + dateTime("timestamp").label("Timestamp") + .description("Current timestamp in UTC format (must be generated by client).") + .required(true) + .metadata( + Map.of( + "type", PropertyType.HEADER)), + string("signature").label("Signature") + .description( + "

Request signature calculated by client. Algorithm for signing is as follows:

  1. Prepare payload for signing: {clientId};{requestId};{timestamp};{uri};{body}
    • Uri example: For full URL https://example.com/MyProject/api/accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02, {uri} value used for calculation is /accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02. Note that leading slash and all query parameters must be included!
    • If request body is not present, use empty string for {body} value.
  2. Using client secret sign the payload with HmacSHA256 algorithm.
  3. Encode resulting signature in base64.
") + .required(true) + .exampleValue("ybHjifCXXHlDNNfY8sOIK9BRoTHlxXYjusUaoN5SCp4=") + .metadata( + Map.of( + "type", PropertyType.HEADER)), + string("iban").label("Iban") + .description("Account IBAN.") + .required(true) + .exampleValue("HR1210010051863000160") + .metadata( + Map.of( + "type", PropertyType.PATH)), + string("dateFrom").label("Date From") + .description("Oldest transaction execution date.") + .required(false) + .exampleValue("2021-01-01") + .metadata( + Map.of( + "type", PropertyType.QUERY)), + string("dateTo").label("Date To") + .description("Newest transaction execution date.") + .required(false) + .exampleValue("2021-01-01") + .metadata( + Map.of( + "type", PropertyType.QUERY)), + integer("lastTransactionId").label("Last Transaction Id") + .description( + "If this parameter is specified, system will return transactions stored after the corresponding transaction.") + .required(false) + .exampleValue(123) + .metadata( + Map.of( + "type", PropertyType.QUERY))) + .output(outputSchema(object().properties(GaurusMyResponseProperties.PROPERTIES) + .metadata( + Map.of( + "responseType", ResponseType.JSON))), + sampleOutput(Map.ofEntries(Map.entry("code", "OK"), Map.entry("message", ""), + Map.entry("hasMoreResults", true), Map.entry("data", "TransactionResult[]")))); + + private GaurusGetAccountTransactionsAction() { + } +} diff --git a/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusGetAccountsAction.java b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusGetAccountsAction.java new file mode 100644 index 00000000000..8358d3435ba --- /dev/null +++ b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusGetAccountsAction.java @@ -0,0 +1,86 @@ +/* + * Copyright 2025 ByteChef + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bytechef.component.gaurus.action; + +import static com.bytechef.component.OpenApiComponentHandler.PropertyType; +import static com.bytechef.component.definition.ComponentDsl.action; +import static com.bytechef.component.definition.ComponentDsl.dateTime; +import static com.bytechef.component.definition.ComponentDsl.object; +import static com.bytechef.component.definition.ComponentDsl.outputSchema; +import static com.bytechef.component.definition.ComponentDsl.sampleOutput; +import static com.bytechef.component.definition.ComponentDsl.string; +import static com.bytechef.component.definition.Context.Http.ResponseType; + +import com.bytechef.component.definition.ComponentDsl; +import com.bytechef.component.gaurus.property.GaurusMyResponseProperties; +import java.util.Map; + +/** + * Provides a list of the component actions. + * + * @generated + * + * @author Igor Beslic + */ +public class GaurusGetAccountsAction { + public static final ComponentDsl.ModifiableActionDefinition ACTION_DEFINITION = action("getAccounts") + .title("Gets accounts for provided client id.") + .description(null) + .metadata( + Map.of( + "method", "GET", + "path", "/accounts" + + )) + .properties(string("clientId").label("Client Id") + .description("Client identifier provided by the system.") + .required(true) + .exampleValue("4181a492-97bf-48ee-b29e-d7d6860c5565") + .metadata( + Map.of( + "type", PropertyType.HEADER)), + string("requestId").label("Request Id") + .description("Unique identifier of a request (must be generated by client).") + .required(true) + .exampleValue("17fcaa13-eb6d-467c-a757-2e669179a19e") + .metadata( + Map.of( + "type", PropertyType.HEADER)), + dateTime("timestamp").label("Timestamp") + .description("Current timestamp in UTC format (must be generated by client).") + .required(true) + .metadata( + Map.of( + "type", PropertyType.HEADER)), + string("signature").label("Signature") + .description( + "

Request signature calculated by client. Algorithm for signing is as follows:

  1. Prepare payload for signing: {clientId};{requestId};{timestamp};{uri};{body}
    • Uri example: For full URL https://example.com/MyProject/api/accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02, {uri} value used for calculation is /accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02. Note that leading slash and all query parameters must be included!
    • If request body is not present, use empty string for {body} value.
  2. Using client secret sign the payload with HmacSHA256 algorithm.
  3. Encode resulting signature in base64.
") + .required(true) + .exampleValue("ybHjifCXXHlDNNfY8sOIK9BRoTHlxXYjusUaoN5SCp4=") + .metadata( + Map.of( + "type", PropertyType.HEADER))) + .output(outputSchema(object().properties(GaurusMyResponseProperties.PROPERTIES) + .metadata( + Map.of( + "responseType", ResponseType.JSON))), + sampleOutput(Map.ofEntries(Map.entry("code", "OK"), Map.entry("message", ""), + Map.entry("hasMoreResults", false), Map.entry("data", "AccountResult[]")))); + + private GaurusGetAccountsAction() { + } +} diff --git a/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusGetExternalUsersAction.java b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusGetExternalUsersAction.java new file mode 100644 index 00000000000..2cc64a16561 --- /dev/null +++ b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusGetExternalUsersAction.java @@ -0,0 +1,98 @@ +/* + * Copyright 2025 ByteChef + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bytechef.component.gaurus.action; + +import static com.bytechef.component.OpenApiComponentHandler.PropertyType; +import static com.bytechef.component.definition.ComponentDsl.action; +import static com.bytechef.component.definition.ComponentDsl.dateTime; +import static com.bytechef.component.definition.ComponentDsl.object; +import static com.bytechef.component.definition.ComponentDsl.outputSchema; +import static com.bytechef.component.definition.ComponentDsl.sampleOutput; +import static com.bytechef.component.definition.ComponentDsl.string; +import static com.bytechef.component.definition.Context.Http.ResponseType; + +import com.bytechef.component.definition.ComponentDsl; +import com.bytechef.component.gaurus.property.GaurusServiceResponseProperties; +import java.util.List; +import java.util.Map; + +/** + * Provides a list of the component actions. + * + * @generated + * @author Igor Beslic + */ +public class GaurusGetExternalUsersAction { + public static final String ENDPOINT_URL = "/external-users"; + public static final ComponentDsl.ModifiableActionDefinition ACTION_DEFINITION = action("getExternalUsers") + .title("Gets external users for provided client id.") + .description(null) + .metadata( + Map.of( + "method", "GET", + "path", "/external-users" + + )) + .properties(string("clientId").label("Client Id") + .description("Client identifier provided by the system.") + .required(true) + .exampleValue("4181a492-97bf-48ee-b29e-d7d6860c5565") + .metadata( + Map.of( + "type", PropertyType.HEADER)), + string("requestId").label("Request Id") + .description("Unique identifier of a request (must be generated by client).") + .required(true) + .exampleValue("17fcaa13-eb6d-467c-a757-2e669179a19e") + .metadata( + Map.of( + "type", PropertyType.HEADER)), + dateTime("timestamp").label("Timestamp") + .description("Current timestamp in UTC format (must be generated by client).") + .required(true) + .metadata( + Map.of( + "type", PropertyType.HEADER)), + string("signature").label("Signature") + .description( + "

Request signature calculated by client. Algorithm for signing is as follows:

  1. Prepare payload for signing: {clientId};{requestId};{timestamp};{uri};{body}
    • Uri example: For full URL https://example.com/MyProject/api/accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02, {uri} value used for calculation is /accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02. Note that leading slash and all query parameters must be included!
    • If request body is not present, use empty string for {body} value.
  2. Using client secret sign the payload with HmacSHA256 algorithm.
  3. Encode resulting signature in base64.
") + .required(true) + .exampleValue("ybHjifCXXHlDNNfY8sOIK9BRoTHlxXYjusUaoN5SCp4=") + .metadata( + Map.of( + "type", PropertyType.HEADER))) + .output(outputSchema(object().properties(GaurusServiceResponseProperties.PROPERTIES) + .description("Standard response wrapper for all API endpoints.") + .metadata( + Map.of( + "responseType", ResponseType.JSON))), + sampleOutput( + Map.ofEntries( + Map.entry("data", + List.of( + Map.ofEntries(Map.entry("id", 42), Map.entry("name", "Pero Perić d.o.o."), + Map.entry("oib", 1.2345678901E10), Map.entry("mail", "pero@example.com"), + Map.entry("bankEntries", + List.of(Map.ofEntries(Map.entry("bankSlug", "erste"), + Map.entry("ibans", List.of("HR1210010051863000160")), + Map.entry("consentJobStatus", "PENDING"))))))), + Map.entry("errors", List.of())))); + + private GaurusGetExternalUsersAction() { + } + +} diff --git a/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusPostExternalUsersAction.java b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusPostExternalUsersAction.java new file mode 100644 index 00000000000..24a82ec5279 --- /dev/null +++ b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusPostExternalUsersAction.java @@ -0,0 +1,100 @@ +/* + * Copyright 2025 ByteChef + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bytechef.component.gaurus.action; + +import static com.bytechef.component.OpenApiComponentHandler.PropertyType; +import static com.bytechef.component.definition.ComponentDsl.action; +import static com.bytechef.component.definition.ComponentDsl.array; +import static com.bytechef.component.definition.ComponentDsl.dateTime; +import static com.bytechef.component.definition.ComponentDsl.object; +import static com.bytechef.component.definition.ComponentDsl.outputSchema; +import static com.bytechef.component.definition.ComponentDsl.sampleOutput; +import static com.bytechef.component.definition.ComponentDsl.string; +import static com.bytechef.component.definition.Context.Http.BodyContentType; +import static com.bytechef.component.definition.Context.Http.ResponseType; + +import com.bytechef.component.definition.ComponentDsl; +import com.bytechef.component.gaurus.property.GaurusExternalUserRequestProperties; +import com.bytechef.component.gaurus.property.GaurusServiceResponseProperties; +import java.util.List; +import java.util.Map; + +/** + * Provides a list of the component actions. + * + * @generated + * + * @author Igor Beslic + */ +public class GaurusPostExternalUsersAction { + public static final ComponentDsl.ModifiableActionDefinition ACTION_DEFINITION = action("postExternalUsers") + .title("Creates external users with bank consent jobs.") + .description(null) + .metadata( + Map.of( + "method", "POST", + "path", "/external-users", "bodyContentType", BodyContentType.JSON, "mimeType", "application/json" + + )) + .properties(string("clientId").label("Client Id") + .description("Client identifier provided by the system.") + .required(true) + .exampleValue("4181a492-97bf-48ee-b29e-d7d6860c5565") + .metadata( + Map.of( + "type", PropertyType.HEADER)), + string("requestId").label("Request Id") + .description("Unique identifier of a request (must be generated by client).") + .required(true) + .exampleValue("17fcaa13-eb6d-467c-a757-2e669179a19e") + .metadata( + Map.of( + "type", PropertyType.HEADER)), + dateTime("timestamp").label("Timestamp") + .description("Current timestamp in UTC format (must be generated by client).") + .required(true) + .metadata( + Map.of( + "type", PropertyType.HEADER)), + string("signature").label("Signature") + .description( + "

Request signature calculated by client. Algorithm for signing is as follows:

  1. Prepare payload for signing: {clientId};{requestId};{timestamp};{uri};{body}
    • Uri example: For full URL https://example.com/MyProject/api/accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02, {uri} value used for calculation is /accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02. Note that leading slash and all query parameters must be included!
    • If request body is not present, use empty string for {body} value.
  2. Using client secret sign the payload with HmacSHA256 algorithm.
  3. Encode resulting signature in base64.
") + .required(true) + .exampleValue("ybHjifCXXHlDNNfY8sOIK9BRoTHlxXYjusUaoN5SCp4=") + .metadata( + Map.of( + "type", PropertyType.HEADER)), + array("__items").items(object().properties(GaurusExternalUserRequestProperties.PROPERTIES)) + .placeholder("Add to Items") + .metadata( + Map.of( + "type", PropertyType.BODY)) + .label("Items") + .required(true)) + .output(outputSchema(object().properties(GaurusServiceResponseProperties.PROPERTIES) + .description("Standard response wrapper for all API endpoints.") + .metadata( + Map.of( + "responseType", ResponseType.JSON))), + sampleOutput(Map.ofEntries(Map.entry("data", + List.of(Map.ofEntries(Map.entry("existingMails", List.of("existing@example.com")), + Map.entry("newMails", List.of("new@example.com"))))), + Map.entry("errors", List.of())))); + + private GaurusPostExternalUsersAction() { + } +} diff --git a/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusPutExternalUserAction.java b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusPutExternalUserAction.java new file mode 100644 index 00000000000..b289c7c75c2 --- /dev/null +++ b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/action/GaurusPutExternalUserAction.java @@ -0,0 +1,83 @@ +/* + * Copyright 2025 ByteChef + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bytechef.component.gaurus.action; + +import static com.bytechef.component.OpenApiComponentHandler.PropertyType; +import static com.bytechef.component.definition.ComponentDsl.action; +import static com.bytechef.component.definition.ComponentDsl.dateTime; +import static com.bytechef.component.definition.ComponentDsl.integer; +import static com.bytechef.component.definition.ComponentDsl.string; + +import com.bytechef.component.definition.ComponentDsl; +import java.util.Map; + +/** + * Provides a list of the component actions. + * + * @generated + * + * @author Igor Beslic + */ +public class GaurusPutExternalUserAction { + public static final ComponentDsl.ModifiableActionDefinition ACTION_DEFINITION = action("putExternalUser") + .title("Updates an external user.") + .description(null) + .metadata( + Map.of( + "method", "PUT", + "path", "/external-users/{externalUserId}" + + )) + .properties(string("clientId").label("Client Id") + .description("Client identifier provided by the system.") + .required(true) + .exampleValue("4181a492-97bf-48ee-b29e-d7d6860c5565") + .metadata( + Map.of( + "type", PropertyType.HEADER)), + string("requestId").label("Request Id") + .description("Unique identifier of a request (must be generated by client).") + .required(true) + .exampleValue("17fcaa13-eb6d-467c-a757-2e669179a19e") + .metadata( + Map.of( + "type", PropertyType.HEADER)), + dateTime("timestamp").label("Timestamp") + .description("Current timestamp in UTC format (must be generated by client).") + .required(true) + .metadata( + Map.of( + "type", PropertyType.HEADER)), + string("signature").label("Signature") + .description( + "

Request signature calculated by client. Algorithm for signing is as follows:

  1. Prepare payload for signing: {clientId};{requestId};{timestamp};{uri};{body}
    • Uri example: For full URL https://example.com/MyProject/api/accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02, {uri} value used for calculation is /accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02. Note that leading slash and all query parameters must be included!
    • If request body is not present, use empty string for {body} value.
  2. Using client secret sign the payload with HmacSHA256 algorithm.
  3. Encode resulting signature in base64.
") + .required(true) + .exampleValue("ybHjifCXXHlDNNfY8sOIK9BRoTHlxXYjusUaoN5SCp4=") + .metadata( + Map.of( + "type", PropertyType.HEADER)), + integer("externalUserId").label("External User Id") + .description("External user identifier.") + .required(true) + .exampleValue(42) + .metadata( + Map.of( + "type", PropertyType.PATH))); + + private GaurusPutExternalUserAction() { + } +} diff --git a/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/connection/GaurusConnection.java b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/connection/GaurusConnection.java new file mode 100644 index 00000000000..ff74cae6e91 --- /dev/null +++ b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/connection/GaurusConnection.java @@ -0,0 +1,56 @@ +/* + * Copyright 2025 ByteChef + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bytechef.component.gaurus.connection; + +import static com.bytechef.component.definition.ComponentDsl.authorization; +import static com.bytechef.component.definition.ComponentDsl.bool; +import static com.bytechef.component.definition.ComponentDsl.connection; +import static com.bytechef.component.definition.ComponentDsl.string; + +import com.bytechef.component.definition.Authorization; +import com.bytechef.component.definition.ComponentDsl; + +/** + * Provides the component connection definition. + * + * @generated + * + * @author Igor Beslic + */ +public class GaurusConnection { + public static final ComponentDsl.ModifiableConnectionDefinition CONNECTION_DEFINITION = connection() + .baseUri((connectionParameters, context) -> "https://bankconnect.gaurus.hr/api/client") + .properties(string("baseUri").label("Service URI") + .description("The base URI of the Gaurus service")) + .authorizationRequired(true) + .authorizations(authorization(Authorization.AuthorizationType.CUSTOM).title("Gaurus HmacSHA256 Authorization") + .properties( + string("clientId").label("Client ID") + .description("Client Id generated at GAURUS") + .required(true), + string("clientSecret").label("Client Secret") + .description("The secret key for digital signing") + .required(true), + bool("allowSelfSignedCert").label("Allow Self-Signed Certificates") + .description("Allow secure connections to servers with self-signed certificates") + .defaultValue(false)) + + ); + + private GaurusConnection() { + } +} diff --git a/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/property/GaurusBankEntryRequestProperties.java b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/property/GaurusBankEntryRequestProperties.java new file mode 100644 index 00000000000..77d1dbc26c4 --- /dev/null +++ b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/property/GaurusBankEntryRequestProperties.java @@ -0,0 +1,49 @@ +/* + * Copyright 2025 ByteChef + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bytechef.component.gaurus.property; + +import static com.bytechef.component.definition.ComponentDsl.array; +import static com.bytechef.component.definition.ComponentDsl.string; + +import com.bytechef.component.definition.ComponentDsl; +import java.util.List; + +/** + * Provides properties definition built from OpenAPI schema. + * + * @generated + */ +public class GaurusBankEntryRequestProperties { + public static final List> PROPERTIES = List.of( + string("bankSlug").label("Bank Slug") + .description("Bank identifier slug.") + .required(false) + .exampleValue("erste"), + array("ibans").items(string().description("List of IBANs.")) + .placeholder("Add to Ibans") + .label("Ibans") + .description("List of IBANs.") + .required(false) + .exampleValue("HR1210010051863000160"), + string("psuIdType").label("Psu Id Type") + .description("PSU ID type for the bank consent.") + .required(false) + .exampleValue("HRIdentificationNumber")); + + private GaurusBankEntryRequestProperties() { + } +} diff --git a/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/property/GaurusErrorDataProperties.java b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/property/GaurusErrorDataProperties.java new file mode 100644 index 00000000000..52bdd997e1f --- /dev/null +++ b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/property/GaurusErrorDataProperties.java @@ -0,0 +1,42 @@ +/* + * Copyright 2025 ByteChef + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bytechef.component.gaurus.property; + +import static com.bytechef.component.definition.ComponentDsl.string; + +import com.bytechef.component.definition.ComponentDsl; +import java.util.List; + +/** + * Provides properties definition built from OpenAPI schema. + * + * @generated + */ +public class GaurusErrorDataProperties { + public static final List> PROPERTIES = List.of( + string("code").label("Code") + .description("Error code.") + .required(false) + .exampleValue("GENERAL_ERROR"), + string("description").label("Description") + .description("Error description.") + .required(false) + .exampleValue("General error")); + + private GaurusErrorDataProperties() { + } +} diff --git a/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/property/GaurusExternalUserRequestProperties.java b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/property/GaurusExternalUserRequestProperties.java new file mode 100644 index 00000000000..94df4fbc619 --- /dev/null +++ b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/property/GaurusExternalUserRequestProperties.java @@ -0,0 +1,53 @@ +/* + * Copyright 2025 ByteChef + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bytechef.component.gaurus.property; + +import static com.bytechef.component.definition.ComponentDsl.array; +import static com.bytechef.component.definition.ComponentDsl.object; +import static com.bytechef.component.definition.ComponentDsl.string; + +import com.bytechef.component.definition.ComponentDsl; +import java.util.List; + +/** + * Provides properties definition built from OpenAPI schema. + * + * @generated + */ +public class GaurusExternalUserRequestProperties { + public static final List> PROPERTIES = List.of( + string("name").label("Name") + .description("External user company name.") + .required(false) + .exampleValue("Pero Perić d.o.o."), + string("oib").label("Oib") + .description("External user OIB (Croatian personal identification number).") + .required(false) + .exampleValue("12345678901"), + string("mail").label("Mail") + .description("External user email address.") + .required(false) + .exampleValue("pero@example.com"), + array("bankEntries").items(object().properties(GaurusBankEntryRequestProperties.PROPERTIES)) + .placeholder("Add to Bank Entries") + .label("Bank Entries") + .description("List of bank entries to create consent jobs for.") + .required(false)); + + private GaurusExternalUserRequestProperties() { + } +} diff --git a/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/property/GaurusMyResponseProperties.java b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/property/GaurusMyResponseProperties.java new file mode 100644 index 00000000000..e812b191db5 --- /dev/null +++ b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/property/GaurusMyResponseProperties.java @@ -0,0 +1,58 @@ +/* + * Copyright 2025 ByteChef + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bytechef.component.gaurus.property; + +import static com.bytechef.component.definition.ComponentDsl.array; +import static com.bytechef.component.definition.ComponentDsl.bool; +import static com.bytechef.component.definition.ComponentDsl.object; +import static com.bytechef.component.definition.ComponentDsl.option; +import static com.bytechef.component.definition.ComponentDsl.string; + +import com.bytechef.component.definition.ComponentDsl; +import java.util.List; + +/** + * Provides properties definition built from OpenAPI schema. + * + * @generated + */ +public class GaurusMyResponseProperties { + public static final List> PROPERTIES = List.of( + string("code").label("Code") + .description("Represents resulting code in case when the system has handled a request.") + .options(option("OK", "OK"), option("VALIDATION_FAILED", "VALIDATION_FAILED"), + option("DATA_UNAVAILABLE", "DATA_UNAVAILABLE"), option("CONSENT_EXPIRED", "CONSENT_EXPIRED"), + option("GENERAL_ERROR", "GENERAL_ERROR")) + .required(false), + string("message").label("Message") + .description("The error message, present only if the \"code\" property is not \"OK\".") + .required(false) + .exampleValue("General error"), + bool("hasMoreResults").label("Has More Results") + .description( + "System limits number of transactions in response. If there are more results related to the request, this flag is set to true. In that case client should initiate a new request with the value of lastTransactionId parameter set to the greatest received transaction identifier plus 1.") + .required(false) + .exampleValue(true), + array("data").items(object().description("List of objects related to the request.")) + .placeholder("Add to Data") + .label("Data") + .description("List of objects related to the request.") + .required(false)); + + private GaurusMyResponseProperties() { + } +} diff --git a/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/property/GaurusServiceResponseProperties.java b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/property/GaurusServiceResponseProperties.java new file mode 100644 index 00000000000..b32e14b96e5 --- /dev/null +++ b/server/libs/modules/components/gaurus/src/main/java/com/bytechef/component/gaurus/property/GaurusServiceResponseProperties.java @@ -0,0 +1,45 @@ +/* + * Copyright 2025 ByteChef + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bytechef.component.gaurus.property; + +import static com.bytechef.component.definition.ComponentDsl.array; +import static com.bytechef.component.definition.ComponentDsl.object; + +import com.bytechef.component.definition.ComponentDsl; +import java.util.List; + +/** + * Provides properties definition built from OpenAPI schema. + * + * @generated + */ +public class GaurusServiceResponseProperties { + public static final List> PROPERTIES = List.of( + array("data").items(object().description("List of results (empty if the response is not valid).")) + .placeholder("Add to Data") + .label("Data") + .description("List of results (empty if the response is not valid).") + .required(false), + array("errors").items(object().properties(GaurusErrorDataProperties.PROPERTIES)) + .placeholder("Add to Errors") + .label("Errors") + .description("List of errors (empty if the response is valid).") + .required(false)); + + private GaurusServiceResponseProperties() { + } +} diff --git a/server/libs/modules/components/gaurus/src/test/java/com/bytechef/component/gaurus/AbstractGaurusComponentHandlerTest.java b/server/libs/modules/components/gaurus/src/test/java/com/bytechef/component/gaurus/AbstractGaurusComponentHandlerTest.java new file mode 100644 index 00000000000..50ccfeb83c2 --- /dev/null +++ b/server/libs/modules/components/gaurus/src/test/java/com/bytechef/component/gaurus/AbstractGaurusComponentHandlerTest.java @@ -0,0 +1,32 @@ +/* + * Copyright 2025 ByteChef + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bytechef.component.gaurus; + +import com.bytechef.test.jsonasssert.JsonFileAssert; +import org.junit.jupiter.api.Test; + +/** + * Provides the base test implementation for the REST based component. + * + * @generated + */ +public abstract class AbstractGaurusComponentHandlerTest { + @Test + public void testGetDefinition() { + JsonFileAssert.assertEquals("definition/gaurus_v1.json", new GaurusComponentHandler().getDefinition()); + } +} diff --git a/server/libs/modules/components/gaurus/src/test/java/com/bytechef/component/gaurus/GaurusComponentHandlerTest.java b/server/libs/modules/components/gaurus/src/test/java/com/bytechef/component/gaurus/GaurusComponentHandlerTest.java new file mode 100644 index 00000000000..387248fdc0e --- /dev/null +++ b/server/libs/modules/components/gaurus/src/test/java/com/bytechef/component/gaurus/GaurusComponentHandlerTest.java @@ -0,0 +1,23 @@ +/* + * Copyright 2025 ByteChef + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.bytechef.component.gaurus; + +/** + * @generated + */ +public class GaurusComponentHandlerTest extends AbstractGaurusComponentHandlerTest { +} diff --git a/server/libs/modules/components/gaurus/src/test/resources/definition/gaurus_v1.json b/server/libs/modules/components/gaurus/src/test/resources/definition/gaurus_v1.json new file mode 100644 index 00000000000..613e26efdfb --- /dev/null +++ b/server/libs/modules/components/gaurus/src/test/resources/definition/gaurus_v1.json @@ -0,0 +1,2492 @@ +{ + "actions": [ { + "batch": null, + "beforeResume": null, + "beforeSuspend": null, + "beforeTimeoutResume": null, + "deprecated": null, + "description": null, + "help": null, + "metadata": { + "method": "DELETE", + "path": "/external-users/{externalUserId}" + }, + "name": "deleteExternalUser", + "outputDefinition": null, + "perform": { }, + "processErrorResponse": null, + "properties": [ { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Client identifier provided by the system.", + "displayCondition": null, + "exampleValue": "4181a492-97bf-48ee-b29e-d7d6860c5565", + "expressionEnabled": null, + "hidden": null, + "label": "Client Id", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "clientId", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Unique identifier of a request (must be generated by client).", + "displayCondition": null, + "exampleValue": "17fcaa13-eb6d-467c-a757-2e669179a19e", + "expressionEnabled": null, + "hidden": null, + "label": "Request Id", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "requestId", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "DATE_TIME", + "defaultValue": null, + "description": "Current timestamp in UTC format (must be generated by client).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": "Timestamp", + "metadata": { + "type": "HEADER" + }, + "name": "timestamp", + "options": null, + "optionsDataSource": null, + "placeholder": null, + "required": true, + "type": "DATE_TIME" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "

Request signature calculated by client. Algorithm for signing is as follows:

  1. Prepare payload for signing: {clientId};{requestId};{timestamp};{uri};{body}
    • Uri example: For full URL https://example.com/MyProject/api/accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02, {uri} value used for calculation is /accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02. Note that leading slash and all query parameters must be included!
    • If request body is not present, use empty string for {body} value.
  2. Using client secret sign the payload with HmacSHA256 algorithm.
  3. Encode resulting signature in base64.
", + "displayCondition": null, + "exampleValue": "ybHjifCXXHlDNNfY8sOIK9BRoTHlxXYjusUaoN5SCp4=", + "expressionEnabled": null, + "hidden": null, + "label": "Signature", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "signature", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "INTEGER", + "defaultValue": null, + "description": "External user identifier.", + "displayCondition": null, + "exampleValue": 42, + "expressionEnabled": null, + "hidden": null, + "label": "External User Id", + "maxValue": null, + "metadata": { + "type": "PATH" + }, + "minValue": null, + "name": "externalUserId", + "options": null, + "optionsDataSource": null, + "placeholder": null, + "required": true, + "type": "INTEGER" + } ], + "resumePerform": null, + "title": "Deletes an external user.", + "workflowNodeDescription": null + }, { + "batch": null, + "beforeResume": null, + "beforeSuspend": null, + "beforeTimeoutResume": null, + "deprecated": null, + "description": null, + "help": null, + "metadata": { + "method": "GET", + "path": "/accounts" + }, + "name": "getAccounts", + "outputDefinition": { + "output": null, + "outputResponse": { + "outputSchema": { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": null, + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { + "responseType": { + "contentType": "application/json", + "type": "JSON" + } + }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": [ { + "advancedOption": null, + "controlType": "SELECT", + "defaultValue": null, + "description": "Represents resulting code in case when the system has handled a request.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": "Code", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "code", + "options": [ { + "description": null, + "label": "OK", + "value": "OK" + }, { + "description": null, + "label": "VALIDATION_FAILED", + "value": "VALIDATION_FAILED" + }, { + "description": null, + "label": "DATA_UNAVAILABLE", + "value": "DATA_UNAVAILABLE" + }, { + "description": null, + "label": "CONSENT_EXPIRED", + "value": "CONSENT_EXPIRED" + }, { + "description": null, + "label": "GENERAL_ERROR", + "value": "GENERAL_ERROR" + } ], + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "The error message, present only if the \"code\" property is not \"OK\".", + "displayCondition": null, + "exampleValue": "General error", + "expressionEnabled": null, + "hidden": null, + "label": "Message", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "message", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "SELECT", + "defaultValue": null, + "description": "System limits number of transactions in response. If there are more results related to the request, this flag is set to true. In that case client should initiate a new request with the value of lastTransactionId parameter set to the greatest received transaction identifier plus 1.", + "displayCondition": null, + "exampleValue": true, + "expressionEnabled": null, + "hidden": null, + "label": "Has More Results", + "metadata": { }, + "name": "hasMoreResults", + "options": [ { + "description": null, + "label": "True", + "value": true + }, { + "description": null, + "label": "False", + "value": false + } ], + "placeholder": null, + "required": false, + "type": "BOOLEAN" + }, { + "advancedOption": null, + "controlType": "ARRAY_BUILDER", + "defaultValue": null, + "description": "List of objects related to the request.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "items": [ { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": "List of objects related to the request.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": null, + "required": null, + "type": "OBJECT" + } ], + "label": "Data", + "maxItems": null, + "metadata": { }, + "minItems": null, + "multipleValues": null, + "name": "data", + "options": null, + "optionsDataSource": null, + "placeholder": "Add to Data", + "required": false, + "type": "ARRAY" + } ], + "required": null, + "type": "OBJECT" + }, + "placeholder": null, + "sampleOutput": { + "hasMoreResults": false, + "data": "AccountResult[]", + "code": "OK", + "message": "" + } + }, + "outputSchema": { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": null, + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { + "responseType": { + "contentType": "application/json", + "type": "JSON" + } + }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": [ { + "advancedOption": null, + "controlType": "SELECT", + "defaultValue": null, + "description": "Represents resulting code in case when the system has handled a request.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": "Code", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "code", + "options": [ { + "description": null, + "label": "OK", + "value": "OK" + }, { + "description": null, + "label": "VALIDATION_FAILED", + "value": "VALIDATION_FAILED" + }, { + "description": null, + "label": "DATA_UNAVAILABLE", + "value": "DATA_UNAVAILABLE" + }, { + "description": null, + "label": "CONSENT_EXPIRED", + "value": "CONSENT_EXPIRED" + }, { + "description": null, + "label": "GENERAL_ERROR", + "value": "GENERAL_ERROR" + } ], + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "The error message, present only if the \"code\" property is not \"OK\".", + "displayCondition": null, + "exampleValue": "General error", + "expressionEnabled": null, + "hidden": null, + "label": "Message", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "message", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "SELECT", + "defaultValue": null, + "description": "System limits number of transactions in response. If there are more results related to the request, this flag is set to true. In that case client should initiate a new request with the value of lastTransactionId parameter set to the greatest received transaction identifier plus 1.", + "displayCondition": null, + "exampleValue": true, + "expressionEnabled": null, + "hidden": null, + "label": "Has More Results", + "metadata": { }, + "name": "hasMoreResults", + "options": [ { + "description": null, + "label": "True", + "value": true + }, { + "description": null, + "label": "False", + "value": false + } ], + "placeholder": null, + "required": false, + "type": "BOOLEAN" + }, { + "advancedOption": null, + "controlType": "ARRAY_BUILDER", + "defaultValue": null, + "description": "List of objects related to the request.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "items": [ { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": "List of objects related to the request.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": null, + "required": null, + "type": "OBJECT" + } ], + "label": "Data", + "maxItems": null, + "metadata": { }, + "minItems": null, + "multipleValues": null, + "name": "data", + "options": null, + "optionsDataSource": null, + "placeholder": "Add to Data", + "required": false, + "type": "ARRAY" + } ], + "required": null, + "type": "OBJECT" + }, + "sampleOutput": { + "hasMoreResults": false, + "data": "AccountResult[]", + "code": "OK", + "message": "" + } + }, + "perform": { }, + "processErrorResponse": null, + "properties": [ { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Client identifier provided by the system.", + "displayCondition": null, + "exampleValue": "4181a492-97bf-48ee-b29e-d7d6860c5565", + "expressionEnabled": null, + "hidden": null, + "label": "Client Id", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "clientId", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Unique identifier of a request (must be generated by client).", + "displayCondition": null, + "exampleValue": "17fcaa13-eb6d-467c-a757-2e669179a19e", + "expressionEnabled": null, + "hidden": null, + "label": "Request Id", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "requestId", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "DATE_TIME", + "defaultValue": null, + "description": "Current timestamp in UTC format (must be generated by client).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": "Timestamp", + "metadata": { + "type": "HEADER" + }, + "name": "timestamp", + "options": null, + "optionsDataSource": null, + "placeholder": null, + "required": true, + "type": "DATE_TIME" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "

Request signature calculated by client. Algorithm for signing is as follows:

  1. Prepare payload for signing: {clientId};{requestId};{timestamp};{uri};{body}
    • Uri example: For full URL https://example.com/MyProject/api/accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02, {uri} value used for calculation is /accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02. Note that leading slash and all query parameters must be included!
    • If request body is not present, use empty string for {body} value.
  2. Using client secret sign the payload with HmacSHA256 algorithm.
  3. Encode resulting signature in base64.
", + "displayCondition": null, + "exampleValue": "ybHjifCXXHlDNNfY8sOIK9BRoTHlxXYjusUaoN5SCp4=", + "expressionEnabled": null, + "hidden": null, + "label": "Signature", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "signature", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + } ], + "resumePerform": null, + "title": "Gets accounts for provided client id.", + "workflowNodeDescription": null + }, { + "batch": null, + "beforeResume": null, + "beforeSuspend": null, + "beforeTimeoutResume": null, + "deprecated": null, + "description": "General rules for query parameters:
  • If lastTransactionid is provided without date parameters system will not set default values for date range (only lastTransactionId will be used for data filtering).
  • Max range between dateFrom and dateTo is 7 days. If provided date range is greater, dateFrom is set to the dateTo minus 7 days.
  • If dateFrom and dateTo are not provided:
    • dateFrom is set to the current date minus 7 days
    • dateTo is set to the current date
  • If dateFrom is provided and dateTo is not provided:
    1. If dateFrom is set to future date, it is set to the current date.
    2. dateTo is set to dateFrom plus 1 day
  • If dateFrom is not provided and dateTo is provided:
    1. If dateTo is set to future date, it is set to the current date.
    2. dateFrom is set to dateTo minus 1 day
", + "help": null, + "metadata": { + "method": "GET", + "path": "/accounts/{iban}/transactions" + }, + "name": "getAccountTransactions", + "outputDefinition": { + "output": null, + "outputResponse": { + "outputSchema": { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": null, + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { + "responseType": { + "contentType": "application/json", + "type": "JSON" + } + }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": [ { + "advancedOption": null, + "controlType": "SELECT", + "defaultValue": null, + "description": "Represents resulting code in case when the system has handled a request.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": "Code", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "code", + "options": [ { + "description": null, + "label": "OK", + "value": "OK" + }, { + "description": null, + "label": "VALIDATION_FAILED", + "value": "VALIDATION_FAILED" + }, { + "description": null, + "label": "DATA_UNAVAILABLE", + "value": "DATA_UNAVAILABLE" + }, { + "description": null, + "label": "CONSENT_EXPIRED", + "value": "CONSENT_EXPIRED" + }, { + "description": null, + "label": "GENERAL_ERROR", + "value": "GENERAL_ERROR" + } ], + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "The error message, present only if the \"code\" property is not \"OK\".", + "displayCondition": null, + "exampleValue": "General error", + "expressionEnabled": null, + "hidden": null, + "label": "Message", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "message", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "SELECT", + "defaultValue": null, + "description": "System limits number of transactions in response. If there are more results related to the request, this flag is set to true. In that case client should initiate a new request with the value of lastTransactionId parameter set to the greatest received transaction identifier plus 1.", + "displayCondition": null, + "exampleValue": true, + "expressionEnabled": null, + "hidden": null, + "label": "Has More Results", + "metadata": { }, + "name": "hasMoreResults", + "options": [ { + "description": null, + "label": "True", + "value": true + }, { + "description": null, + "label": "False", + "value": false + } ], + "placeholder": null, + "required": false, + "type": "BOOLEAN" + }, { + "advancedOption": null, + "controlType": "ARRAY_BUILDER", + "defaultValue": null, + "description": "List of objects related to the request.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "items": [ { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": "List of objects related to the request.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": null, + "required": null, + "type": "OBJECT" + } ], + "label": "Data", + "maxItems": null, + "metadata": { }, + "minItems": null, + "multipleValues": null, + "name": "data", + "options": null, + "optionsDataSource": null, + "placeholder": "Add to Data", + "required": false, + "type": "ARRAY" + } ], + "required": null, + "type": "OBJECT" + }, + "placeholder": null, + "sampleOutput": { + "hasMoreResults": true, + "data": "TransactionResult[]", + "code": "OK", + "message": "" + } + }, + "outputSchema": { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": null, + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { + "responseType": { + "contentType": "application/json", + "type": "JSON" + } + }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": [ { + "advancedOption": null, + "controlType": "SELECT", + "defaultValue": null, + "description": "Represents resulting code in case when the system has handled a request.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": "Code", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "code", + "options": [ { + "description": null, + "label": "OK", + "value": "OK" + }, { + "description": null, + "label": "VALIDATION_FAILED", + "value": "VALIDATION_FAILED" + }, { + "description": null, + "label": "DATA_UNAVAILABLE", + "value": "DATA_UNAVAILABLE" + }, { + "description": null, + "label": "CONSENT_EXPIRED", + "value": "CONSENT_EXPIRED" + }, { + "description": null, + "label": "GENERAL_ERROR", + "value": "GENERAL_ERROR" + } ], + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "The error message, present only if the \"code\" property is not \"OK\".", + "displayCondition": null, + "exampleValue": "General error", + "expressionEnabled": null, + "hidden": null, + "label": "Message", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "message", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "SELECT", + "defaultValue": null, + "description": "System limits number of transactions in response. If there are more results related to the request, this flag is set to true. In that case client should initiate a new request with the value of lastTransactionId parameter set to the greatest received transaction identifier plus 1.", + "displayCondition": null, + "exampleValue": true, + "expressionEnabled": null, + "hidden": null, + "label": "Has More Results", + "metadata": { }, + "name": "hasMoreResults", + "options": [ { + "description": null, + "label": "True", + "value": true + }, { + "description": null, + "label": "False", + "value": false + } ], + "placeholder": null, + "required": false, + "type": "BOOLEAN" + }, { + "advancedOption": null, + "controlType": "ARRAY_BUILDER", + "defaultValue": null, + "description": "List of objects related to the request.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "items": [ { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": "List of objects related to the request.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": null, + "required": null, + "type": "OBJECT" + } ], + "label": "Data", + "maxItems": null, + "metadata": { }, + "minItems": null, + "multipleValues": null, + "name": "data", + "options": null, + "optionsDataSource": null, + "placeholder": "Add to Data", + "required": false, + "type": "ARRAY" + } ], + "required": null, + "type": "OBJECT" + }, + "sampleOutput": { + "hasMoreResults": true, + "data": "TransactionResult[]", + "code": "OK", + "message": "" + } + }, + "perform": { }, + "processErrorResponse": null, + "properties": [ { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Client identifier provided by the system.", + "displayCondition": null, + "exampleValue": "4181a492-97bf-48ee-b29e-d7d6860c5565", + "expressionEnabled": null, + "hidden": null, + "label": "Client Id", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "clientId", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Unique identifier of a request (must be generated by client).", + "displayCondition": null, + "exampleValue": "17fcaa13-eb6d-467c-a757-2e669179a19e", + "expressionEnabled": null, + "hidden": null, + "label": "Request Id", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "requestId", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "DATE_TIME", + "defaultValue": null, + "description": "Current timestamp in UTC format (must be generated by client).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": "Timestamp", + "metadata": { + "type": "HEADER" + }, + "name": "timestamp", + "options": null, + "optionsDataSource": null, + "placeholder": null, + "required": true, + "type": "DATE_TIME" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "

Request signature calculated by client. Algorithm for signing is as follows:

  1. Prepare payload for signing: {clientId};{requestId};{timestamp};{uri};{body}
    • Uri example: For full URL https://example.com/MyProject/api/accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02, {uri} value used for calculation is /accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02. Note that leading slash and all query parameters must be included!
    • If request body is not present, use empty string for {body} value.
  2. Using client secret sign the payload with HmacSHA256 algorithm.
  3. Encode resulting signature in base64.
", + "displayCondition": null, + "exampleValue": "ybHjifCXXHlDNNfY8sOIK9BRoTHlxXYjusUaoN5SCp4=", + "expressionEnabled": null, + "hidden": null, + "label": "Signature", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "signature", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Account IBAN.", + "displayCondition": null, + "exampleValue": "HR1210010051863000160", + "expressionEnabled": null, + "hidden": null, + "label": "Iban", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "PATH" + }, + "minLength": null, + "name": "iban", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Oldest transaction execution date.", + "displayCondition": null, + "exampleValue": "2021-01-01", + "expressionEnabled": null, + "hidden": null, + "label": "Date From", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "QUERY" + }, + "minLength": null, + "name": "dateFrom", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Newest transaction execution date.", + "displayCondition": null, + "exampleValue": "2021-01-01", + "expressionEnabled": null, + "hidden": null, + "label": "Date To", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "QUERY" + }, + "minLength": null, + "name": "dateTo", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "INTEGER", + "defaultValue": null, + "description": "If this parameter is specified, system will return transactions stored after the corresponding transaction.", + "displayCondition": null, + "exampleValue": 123, + "expressionEnabled": null, + "hidden": null, + "label": "Last Transaction Id", + "maxValue": null, + "metadata": { + "type": "QUERY" + }, + "minValue": null, + "name": "lastTransactionId", + "options": null, + "optionsDataSource": null, + "placeholder": null, + "required": false, + "type": "INTEGER" + } ], + "resumePerform": null, + "title": "Gets transactions for provided IBAN and query parameters.", + "workflowNodeDescription": null + }, { + "batch": null, + "beforeResume": null, + "beforeSuspend": null, + "beforeTimeoutResume": null, + "deprecated": null, + "description": null, + "help": null, + "metadata": { + "method": "GET", + "path": "/external-users" + }, + "name": "getExternalUsers", + "outputDefinition": { + "output": null, + "outputResponse": { + "outputSchema": { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": "Standard response wrapper for all API endpoints.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { + "responseType": { + "contentType": "application/json", + "type": "JSON" + } + }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": [ { + "advancedOption": null, + "controlType": "ARRAY_BUILDER", + "defaultValue": null, + "description": "List of results (empty if the response is not valid).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "items": [ { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": "List of results (empty if the response is not valid).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": null, + "required": null, + "type": "OBJECT" + } ], + "label": "Data", + "maxItems": null, + "metadata": { }, + "minItems": null, + "multipleValues": null, + "name": "data", + "options": null, + "optionsDataSource": null, + "placeholder": "Add to Data", + "required": false, + "type": "ARRAY" + }, { + "advancedOption": null, + "controlType": "ARRAY_BUILDER", + "defaultValue": null, + "description": "List of errors (empty if the response is valid).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "items": [ { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": null, + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": [ { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Error code.", + "displayCondition": null, + "exampleValue": "GENERAL_ERROR", + "expressionEnabled": null, + "hidden": null, + "label": "Code", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "code", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Error description.", + "displayCondition": null, + "exampleValue": "General error", + "expressionEnabled": null, + "hidden": null, + "label": "Description", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "description", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + } ], + "required": null, + "type": "OBJECT" + } ], + "label": "Errors", + "maxItems": null, + "metadata": { }, + "minItems": null, + "multipleValues": null, + "name": "errors", + "options": null, + "optionsDataSource": null, + "placeholder": "Add to Errors", + "required": false, + "type": "ARRAY" + } ], + "required": null, + "type": "OBJECT" + }, + "placeholder": null, + "sampleOutput": { + "data": [ { + "oib": 1.2345678901E10, + "id": 42, + "bankEntries": [ { + "bankSlug": "erste", + "ibans": [ "HR1210010051863000160" ], + "consentJobStatus": "PENDING" + } ], + "name": "Pero Perić d.o.o.", + "mail": "pero@example.com" + } ], + "errors": [ ] + } + }, + "outputSchema": { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": "Standard response wrapper for all API endpoints.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { + "responseType": { + "contentType": "application/json", + "type": "JSON" + } + }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": [ { + "advancedOption": null, + "controlType": "ARRAY_BUILDER", + "defaultValue": null, + "description": "List of results (empty if the response is not valid).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "items": [ { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": "List of results (empty if the response is not valid).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": null, + "required": null, + "type": "OBJECT" + } ], + "label": "Data", + "maxItems": null, + "metadata": { }, + "minItems": null, + "multipleValues": null, + "name": "data", + "options": null, + "optionsDataSource": null, + "placeholder": "Add to Data", + "required": false, + "type": "ARRAY" + }, { + "advancedOption": null, + "controlType": "ARRAY_BUILDER", + "defaultValue": null, + "description": "List of errors (empty if the response is valid).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "items": [ { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": null, + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": [ { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Error code.", + "displayCondition": null, + "exampleValue": "GENERAL_ERROR", + "expressionEnabled": null, + "hidden": null, + "label": "Code", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "code", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Error description.", + "displayCondition": null, + "exampleValue": "General error", + "expressionEnabled": null, + "hidden": null, + "label": "Description", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "description", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + } ], + "required": null, + "type": "OBJECT" + } ], + "label": "Errors", + "maxItems": null, + "metadata": { }, + "minItems": null, + "multipleValues": null, + "name": "errors", + "options": null, + "optionsDataSource": null, + "placeholder": "Add to Errors", + "required": false, + "type": "ARRAY" + } ], + "required": null, + "type": "OBJECT" + }, + "sampleOutput": { + "data": [ { + "oib": 1.2345678901E10, + "id": 42, + "bankEntries": [ { + "bankSlug": "erste", + "ibans": [ "HR1210010051863000160" ], + "consentJobStatus": "PENDING" + } ], + "name": "Pero Perić d.o.o.", + "mail": "pero@example.com" + } ], + "errors": [ ] + } + }, + "perform": { }, + "processErrorResponse": null, + "properties": [ { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Client identifier provided by the system.", + "displayCondition": null, + "exampleValue": "4181a492-97bf-48ee-b29e-d7d6860c5565", + "expressionEnabled": null, + "hidden": null, + "label": "Client Id", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "clientId", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Unique identifier of a request (must be generated by client).", + "displayCondition": null, + "exampleValue": "17fcaa13-eb6d-467c-a757-2e669179a19e", + "expressionEnabled": null, + "hidden": null, + "label": "Request Id", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "requestId", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "DATE_TIME", + "defaultValue": null, + "description": "Current timestamp in UTC format (must be generated by client).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": "Timestamp", + "metadata": { + "type": "HEADER" + }, + "name": "timestamp", + "options": null, + "optionsDataSource": null, + "placeholder": null, + "required": true, + "type": "DATE_TIME" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "

Request signature calculated by client. Algorithm for signing is as follows:

  1. Prepare payload for signing: {clientId};{requestId};{timestamp};{uri};{body}
    • Uri example: For full URL https://example.com/MyProject/api/accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02, {uri} value used for calculation is /accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02. Note that leading slash and all query parameters must be included!
    • If request body is not present, use empty string for {body} value.
  2. Using client secret sign the payload with HmacSHA256 algorithm.
  3. Encode resulting signature in base64.
", + "displayCondition": null, + "exampleValue": "ybHjifCXXHlDNNfY8sOIK9BRoTHlxXYjusUaoN5SCp4=", + "expressionEnabled": null, + "hidden": null, + "label": "Signature", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "signature", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + } ], + "resumePerform": null, + "title": "Gets external users for provided client id.", + "workflowNodeDescription": null + }, { + "batch": null, + "beforeResume": null, + "beforeSuspend": null, + "beforeTimeoutResume": null, + "deprecated": null, + "description": null, + "help": null, + "metadata": { + "path": "/external-users", + "mimeType": "application/json", + "method": "POST", + "bodyContentType": "JSON" + }, + "name": "postExternalUsers", + "outputDefinition": { + "output": null, + "outputResponse": { + "outputSchema": { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": "Standard response wrapper for all API endpoints.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { + "responseType": { + "contentType": "application/json", + "type": "JSON" + } + }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": [ { + "advancedOption": null, + "controlType": "ARRAY_BUILDER", + "defaultValue": null, + "description": "List of results (empty if the response is not valid).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "items": [ { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": "List of results (empty if the response is not valid).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": null, + "required": null, + "type": "OBJECT" + } ], + "label": "Data", + "maxItems": null, + "metadata": { }, + "minItems": null, + "multipleValues": null, + "name": "data", + "options": null, + "optionsDataSource": null, + "placeholder": "Add to Data", + "required": false, + "type": "ARRAY" + }, { + "advancedOption": null, + "controlType": "ARRAY_BUILDER", + "defaultValue": null, + "description": "List of errors (empty if the response is valid).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "items": [ { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": null, + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": [ { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Error code.", + "displayCondition": null, + "exampleValue": "GENERAL_ERROR", + "expressionEnabled": null, + "hidden": null, + "label": "Code", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "code", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Error description.", + "displayCondition": null, + "exampleValue": "General error", + "expressionEnabled": null, + "hidden": null, + "label": "Description", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "description", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + } ], + "required": null, + "type": "OBJECT" + } ], + "label": "Errors", + "maxItems": null, + "metadata": { }, + "minItems": null, + "multipleValues": null, + "name": "errors", + "options": null, + "optionsDataSource": null, + "placeholder": "Add to Errors", + "required": false, + "type": "ARRAY" + } ], + "required": null, + "type": "OBJECT" + }, + "placeholder": null, + "sampleOutput": { + "data": [ { + "newMails": [ "new@example.com" ], + "existingMails": [ "existing@example.com" ] + } ], + "errors": [ ] + } + }, + "outputSchema": { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": "Standard response wrapper for all API endpoints.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { + "responseType": { + "contentType": "application/json", + "type": "JSON" + } + }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": [ { + "advancedOption": null, + "controlType": "ARRAY_BUILDER", + "defaultValue": null, + "description": "List of results (empty if the response is not valid).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "items": [ { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": "List of results (empty if the response is not valid).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": null, + "required": null, + "type": "OBJECT" + } ], + "label": "Data", + "maxItems": null, + "metadata": { }, + "minItems": null, + "multipleValues": null, + "name": "data", + "options": null, + "optionsDataSource": null, + "placeholder": "Add to Data", + "required": false, + "type": "ARRAY" + }, { + "advancedOption": null, + "controlType": "ARRAY_BUILDER", + "defaultValue": null, + "description": "List of errors (empty if the response is valid).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "items": [ { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": null, + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": [ { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Error code.", + "displayCondition": null, + "exampleValue": "GENERAL_ERROR", + "expressionEnabled": null, + "hidden": null, + "label": "Code", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "code", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Error description.", + "displayCondition": null, + "exampleValue": "General error", + "expressionEnabled": null, + "hidden": null, + "label": "Description", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "description", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + } ], + "required": null, + "type": "OBJECT" + } ], + "label": "Errors", + "maxItems": null, + "metadata": { }, + "minItems": null, + "multipleValues": null, + "name": "errors", + "options": null, + "optionsDataSource": null, + "placeholder": "Add to Errors", + "required": false, + "type": "ARRAY" + } ], + "required": null, + "type": "OBJECT" + }, + "sampleOutput": { + "data": [ { + "newMails": [ "new@example.com" ], + "existingMails": [ "existing@example.com" ] + } ], + "errors": [ ] + } + }, + "perform": { }, + "processErrorResponse": null, + "properties": [ { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Client identifier provided by the system.", + "displayCondition": null, + "exampleValue": "4181a492-97bf-48ee-b29e-d7d6860c5565", + "expressionEnabled": null, + "hidden": null, + "label": "Client Id", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "clientId", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Unique identifier of a request (must be generated by client).", + "displayCondition": null, + "exampleValue": "17fcaa13-eb6d-467c-a757-2e669179a19e", + "expressionEnabled": null, + "hidden": null, + "label": "Request Id", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "requestId", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "DATE_TIME", + "defaultValue": null, + "description": "Current timestamp in UTC format (must be generated by client).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": "Timestamp", + "metadata": { + "type": "HEADER" + }, + "name": "timestamp", + "options": null, + "optionsDataSource": null, + "placeholder": null, + "required": true, + "type": "DATE_TIME" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "

Request signature calculated by client. Algorithm for signing is as follows:

  1. Prepare payload for signing: {clientId};{requestId};{timestamp};{uri};{body}
    • Uri example: For full URL https://example.com/MyProject/api/accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02, {uri} value used for calculation is /accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02. Note that leading slash and all query parameters must be included!
    • If request body is not present, use empty string for {body} value.
  2. Using client secret sign the payload with HmacSHA256 algorithm.
  3. Encode resulting signature in base64.
", + "displayCondition": null, + "exampleValue": "ybHjifCXXHlDNNfY8sOIK9BRoTHlxXYjusUaoN5SCp4=", + "expressionEnabled": null, + "hidden": null, + "label": "Signature", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "signature", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "ARRAY_BUILDER", + "defaultValue": null, + "description": null, + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "items": [ { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": null, + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": [ { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "External user company name.", + "displayCondition": null, + "exampleValue": "Pero Perić d.o.o.", + "expressionEnabled": null, + "hidden": null, + "label": "Name", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "name", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "External user OIB (Croatian personal identification number).", + "displayCondition": null, + "exampleValue": "12345678901", + "expressionEnabled": null, + "hidden": null, + "label": "Oib", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "oib", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "External user email address.", + "displayCondition": null, + "exampleValue": "pero@example.com", + "expressionEnabled": null, + "hidden": null, + "label": "Mail", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "mail", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "ARRAY_BUILDER", + "defaultValue": null, + "description": "List of bank entries to create consent jobs for.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "items": [ { + "additionalProperties": null, + "advancedOption": null, + "controlType": "OBJECT_BUILDER", + "defaultValue": null, + "description": null, + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "metadata": { }, + "multipleValues": null, + "name": null, + "options": null, + "optionsDataSource": null, + "placeholder": null, + "properties": [ { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Bank identifier slug.", + "displayCondition": null, + "exampleValue": "erste", + "expressionEnabled": null, + "hidden": null, + "label": "Bank Slug", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "bankSlug", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "ARRAY_BUILDER", + "defaultValue": null, + "description": "List of IBANs.", + "displayCondition": null, + "exampleValue": [ "HR1210010051863000160" ], + "expressionEnabled": null, + "hidden": null, + "items": [ { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "List of IBANs.", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": null, + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": null, + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": null, + "type": "STRING" + } ], + "label": "Ibans", + "maxItems": null, + "metadata": { }, + "minItems": null, + "multipleValues": null, + "name": "ibans", + "options": null, + "optionsDataSource": null, + "placeholder": "Add to Ibans", + "required": false, + "type": "ARRAY" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "PSU ID type for the bank consent.", + "displayCondition": null, + "exampleValue": "HRIdentificationNumber", + "expressionEnabled": null, + "hidden": null, + "label": "Psu Id Type", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "psuIdType", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": false, + "type": "STRING" + } ], + "required": null, + "type": "OBJECT" + } ], + "label": "Bank Entries", + "maxItems": null, + "metadata": { }, + "minItems": null, + "multipleValues": null, + "name": "bankEntries", + "options": null, + "optionsDataSource": null, + "placeholder": "Add to Bank Entries", + "required": false, + "type": "ARRAY" + } ], + "required": null, + "type": "OBJECT" + } ], + "label": "Items", + "maxItems": null, + "metadata": { + "type": "BODY" + }, + "minItems": null, + "multipleValues": null, + "name": "__items", + "options": null, + "optionsDataSource": null, + "placeholder": "Add to Items", + "required": true, + "type": "ARRAY" + } ], + "resumePerform": null, + "title": "Creates external users with bank consent jobs.", + "workflowNodeDescription": null + }, { + "batch": null, + "beforeResume": null, + "beforeSuspend": null, + "beforeTimeoutResume": null, + "deprecated": null, + "description": null, + "help": null, + "metadata": { + "method": "PUT", + "path": "/external-users/{externalUserId}" + }, + "name": "putExternalUser", + "outputDefinition": null, + "perform": { }, + "processErrorResponse": null, + "properties": [ { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Client identifier provided by the system.", + "displayCondition": null, + "exampleValue": "4181a492-97bf-48ee-b29e-d7d6860c5565", + "expressionEnabled": null, + "hidden": null, + "label": "Client Id", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "clientId", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Unique identifier of a request (must be generated by client).", + "displayCondition": null, + "exampleValue": "17fcaa13-eb6d-467c-a757-2e669179a19e", + "expressionEnabled": null, + "hidden": null, + "label": "Request Id", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "requestId", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "DATE_TIME", + "defaultValue": null, + "description": "Current timestamp in UTC format (must be generated by client).", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": "Timestamp", + "metadata": { + "type": "HEADER" + }, + "name": "timestamp", + "options": null, + "optionsDataSource": null, + "placeholder": null, + "required": true, + "type": "DATE_TIME" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "

Request signature calculated by client. Algorithm for signing is as follows:

  1. Prepare payload for signing: {clientId};{requestId};{timestamp};{uri};{body}
    • Uri example: For full URL https://example.com/MyProject/api/accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02, {uri} value used for calculation is /accounts/{IBAN}/transactions?dateFrom=2021-01-01&dateTo=2021-01-02. Note that leading slash and all query parameters must be included!
    • If request body is not present, use empty string for {body} value.
  2. Using client secret sign the payload with HmacSHA256 algorithm.
  3. Encode resulting signature in base64.
", + "displayCondition": null, + "exampleValue": "ybHjifCXXHlDNNfY8sOIK9BRoTHlxXYjusUaoN5SCp4=", + "expressionEnabled": null, + "hidden": null, + "label": "Signature", + "languageId": null, + "maxLength": null, + "metadata": { + "type": "HEADER" + }, + "minLength": null, + "name": "signature", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "INTEGER", + "defaultValue": null, + "description": "External user identifier.", + "displayCondition": null, + "exampleValue": 42, + "expressionEnabled": null, + "hidden": null, + "label": "External User Id", + "maxValue": null, + "metadata": { + "type": "PATH" + }, + "minValue": null, + "name": "externalUserId", + "options": null, + "optionsDataSource": null, + "placeholder": null, + "required": true, + "type": "INTEGER" + } ], + "resumePerform": null, + "title": "Updates an external user.", + "workflowNodeDescription": null + } ], + "clusterElements": null, + "componentCategories": null, + "connection": { + "authorizationRequired": true, + "authorizations": [ { + "acquire": null, + "apply": null, + "authorizationCallback": null, + "authorizationUrl": null, + "clientId": null, + "clientSecret": null, + "description": null, + "detectOn": null, + "name": "custom", + "oauth2AuthorizationExtraQueryParameters": null, + "pkce": null, + "properties": [ { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "Client Id generated at GAURUS", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": "Client ID", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "clientId", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "The secret key for digital signing", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": "Client Secret", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "clientSecret", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": true, + "type": "STRING" + }, { + "advancedOption": null, + "controlType": "SELECT", + "defaultValue": false, + "description": "Allow secure connections to servers with self-signed certificates", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": "Allow Self-Signed Certificates", + "metadata": { }, + "name": "allowSelfSignedCert", + "options": [ { + "description": null, + "label": "True", + "value": true + }, { + "description": null, + "label": "False", + "value": false + } ], + "placeholder": null, + "required": null, + "type": "BOOLEAN" + } ], + "refresh": null, + "refreshOn": null, + "refreshToken": null, + "refreshUrl": null, + "scopes": null, + "title": "Gaurus HmacSHA256 Authorization", + "tokenUrl": null, + "type": "CUSTOM" + } ], + "baseUri": { }, + "help": null, + "processErrorResponse": null, + "properties": [ { + "advancedOption": null, + "controlType": "TEXT", + "defaultValue": null, + "description": "The base URI of the Gaurus service", + "displayCondition": null, + "exampleValue": null, + "expressionEnabled": null, + "hidden": null, + "label": "Service URI", + "languageId": null, + "maxLength": null, + "metadata": { }, + "minLength": null, + "name": "baseUri", + "options": null, + "optionsDataSource": null, + "optionsLoadedDynamically": null, + "placeholder": null, + "regex": null, + "required": null, + "type": "STRING" + } ], + "test": null, + "version": 1 + }, + "customAction": null, + "customActionHelp": null, + "description": "Bank Connect API specification", + "icon": null, + "metadata": null, + "name": "gaurus", + "resources": null, + "tags": null, + "title": "Bank Connect", + "triggers": [ ], + "unifiedApi": null, + "version": 1 +} \ No newline at end of file diff --git a/server/libs/platform/platform-component/platform-component-context/platform-component-context-service/build.gradle.kts b/server/libs/platform/platform-component/platform-component-context/platform-component-context-service/build.gradle.kts index 2464f09763d..99cdec65702 100644 --- a/server/libs/platform/platform-component/platform-component-context/platform-component-context-service/build.gradle.kts +++ b/server/libs/platform/platform-component/platform-component-context/platform-component-context-service/build.gradle.kts @@ -1,4 +1,5 @@ dependencies { + implementation("io.micrometer:micrometer-tracing") implementation(libs.com.github.mizosoft.methanol) implementation("org.apache.commons:commons-lang3") implementation(libs.commons.text) diff --git a/server/libs/platform/platform-component/platform-component-context/platform-component-context-service/src/main/java/com/bytechef/platform/component/context/ActionContextImpl.java b/server/libs/platform/platform-component/platform-component-context/platform-component-context-service/src/main/java/com/bytechef/platform/component/context/ActionContextImpl.java index 81e0c70e6e2..5156785e94b 100644 --- a/server/libs/platform/platform-component/platform-component-context/platform-component-context-service/src/main/java/com/bytechef/platform/component/context/ActionContextImpl.java +++ b/server/libs/platform/platform-component/platform-component-context/platform-component-context-service/src/main/java/com/bytechef/platform/component/context/ActionContextImpl.java @@ -30,9 +30,12 @@ import com.bytechef.platform.workflow.execution.ApprovalId; import com.bytechef.platform.workflow.execution.JobResumeId; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import io.micrometer.tracing.TraceContext; +import io.micrometer.tracing.Tracer; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.UUID; import java.util.function.Consumer; import org.apache.commons.lang3.Validate; import org.jspecify.annotations.Nullable; @@ -63,6 +66,7 @@ class ActionContextImpl extends ContextImpl implements ActionContext, ActionCont private final @Nullable String publicUrl; private final long taskExecutionId; private final TempFileStorage tempFileStorage; + private final @Nullable Tracer tracer; private final @Nullable String workflowId; private final @Nullable Long environmentId; @@ -82,6 +86,7 @@ private ActionContextImpl(Builder builder) { this.logFileStorageWriter = builder.logFileStorageWriter; this.taskExecutionId = builder.taskExecutionId; this.tempFileStorage = builder.tempFileStorage; + this.tracer = builder.tracer; if (builder.jobId != null && builder.publicUrl != null) { this.approval = new ApprovalImpl(builder.jobId, builder.publicUrl); @@ -152,6 +157,7 @@ static final class Builder { private @Nullable LogFileStorageWriter logFileStorageWriter; private @Nullable String publicUrl; private long taskExecutionId; + private @Nullable Tracer tracer; private final TempFileStorage tempFileStorage; private @Nullable PlatformType type; private @Nullable String workflowId; @@ -178,6 +184,12 @@ Builder componentConnection(@Nullable ComponentConnection componentConnection) { return this; } + Builder tracer(@Nullable Tracer tracer) { + this.tracer = tracer; + + return this; + } + Builder environmentId(@Nullable Long environmentId) { this.environmentId = environmentId; @@ -237,6 +249,24 @@ ActionContextImpl build() { } } + @Override + public String getTraceId() { + if (tracer == null) { + return UUID.randomUUID() + .toString(); + } + + TraceContext context = tracer.currentTraceContext() + .context(); + + if (context == null) { + return UUID.randomUUID() + .toString(); + } + + return context.traceId(); + } + @Override public Links approval(ContextFunction approvalFunction) { try { diff --git a/server/libs/platform/platform-component/platform-component-context/platform-component-context-service/src/main/java/com/bytechef/platform/component/context/ContextFactoryImpl.java b/server/libs/platform/platform-component/platform-component-context/platform-component-context-service/src/main/java/com/bytechef/platform/component/context/ContextFactoryImpl.java index add3e135c96..e7ba00e84c7 100644 --- a/server/libs/platform/platform-component/platform-component-context/platform-component-context-service/src/main/java/com/bytechef/platform/component/context/ContextFactoryImpl.java +++ b/server/libs/platform/platform-component/platform-component-context/platform-component-context-service/src/main/java/com/bytechef/platform/component/context/ContextFactoryImpl.java @@ -31,6 +31,7 @@ import com.bytechef.platform.data.storage.DataStorage; import com.bytechef.platform.file.storage.TempFileStorage; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import io.micrometer.tracing.Tracer; import org.jspecify.annotations.Nullable; import org.springframework.cache.CacheManager; import org.springframework.context.ApplicationContext; @@ -52,13 +53,14 @@ public class ContextFactoryImpl implements ContextFactory { private final LogFileStorage logFileStorage; private final TempFileStorage tempFileStorage; private final String publicUrl; + private final Tracer tracer; @SuppressFBWarnings("EI") public ContextFactoryImpl( ApplicationContext applicationContext, ApplicationProperties applicationProperties, CacheManager cacheManager, DataStorage dataStorage, ApplicationEventPublisher eventPublisher, FileStorageServiceRegistry fileStorageServiceRegistry, LogFileStorage logFileStorage, - TempFileStorage tempFileStorage) { + TempFileStorage tempFileStorage, Tracer tracer) { this.applicationContext = applicationContext; this.cacheManager = cacheManager; @@ -74,6 +76,7 @@ public ContextFactoryImpl( this.eventPublisher = eventPublisher; this.logFileStorage = logFileStorage; this.tempFileStorage = tempFileStorage; + this.tracer = tracer; this.publicUrl = applicationProperties.getPublicUrl(); } @@ -97,6 +100,7 @@ eventPublisher, getHttpClientExecutor(editorEnvironment), getTempFileStorage(edi .publicUrl(publicUrl) .taskExecutionId(taskExecutionId != null ? taskExecutionId : 0) .type(type) + .tracer(tracer) .workflowId(workflowId) .build(); } diff --git a/server/libs/platform/platform-component/platform-component-service/build.gradle.kts b/server/libs/platform/platform-component/platform-component-service/build.gradle.kts index 18ec5bbf69c..1e1504a45ff 100644 --- a/server/libs/platform/platform-component/platform-component-service/build.gradle.kts +++ b/server/libs/platform/platform-component/platform-component-service/build.gradle.kts @@ -1,4 +1,5 @@ dependencies { + implementation(("io.micrometer:micrometer-tracing")) implementation(libs.com.github.mizosoft.methanol) implementation("org.apache.commons:commons-lang3") implementation("org.aspectj:aspectjweaver") diff --git a/server/libs/platform/platform-component/platform-component-service/src/main/java/com/bytechef/platform/component/definition/ActionContextAdapater.java b/server/libs/platform/platform-component/platform-component-service/src/main/java/com/bytechef/platform/component/definition/ActionContextAdapater.java index 95bd2abf404..1d9be66937b 100644 --- a/server/libs/platform/platform-component/platform-component-service/src/main/java/com/bytechef/platform/component/definition/ActionContextAdapater.java +++ b/server/libs/platform/platform-component/platform-component-service/src/main/java/com/bytechef/platform/component/definition/ActionContextAdapater.java @@ -101,6 +101,11 @@ public void suspend(Suspend suspend) { throw new UnsupportedOperationException(); } + @Override + public String getTraceId() { + throw new UnsupportedOperationException(); + } + @Override public R xml(ContextFunction xmlFunction) { return context.xml(xmlFunction); diff --git a/server/libs/platform/platform-component/platform-component-service/src/test/java/com/bytechef/platform/component/config/ComponentDefinitionIntTestConfiguration.java b/server/libs/platform/platform-component/platform-component-service/src/test/java/com/bytechef/platform/component/config/ComponentDefinitionIntTestConfiguration.java index 322c59f8561..268c6147b09 100644 --- a/server/libs/platform/platform-component/platform-component-service/src/test/java/com/bytechef/platform/component/config/ComponentDefinitionIntTestConfiguration.java +++ b/server/libs/platform/platform-component/platform-component-service/src/test/java/com/bytechef/platform/component/config/ComponentDefinitionIntTestConfiguration.java @@ -18,7 +18,10 @@ import com.bytechef.jackson.config.JacksonConfiguration; import com.bytechef.liquibase.config.LiquibaseConfiguration; +import io.micrometer.tracing.Tracer; +import org.mockito.Mockito; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -34,4 +37,9 @@ @Configuration public class ComponentDefinitionIntTestConfiguration { + @Bean + Tracer tracer() { + return Mockito.mock(Tracer.class); + } + } diff --git a/server/libs/platform/platform-component/platform-component-test-int-support/build.gradle.kts b/server/libs/platform/platform-component/platform-component-test-int-support/build.gradle.kts index 0b0ad6b563f..c09cca3a8d8 100644 --- a/server/libs/platform/platform-component/platform-component-test-int-support/build.gradle.kts +++ b/server/libs/platform/platform-component/platform-component-test-int-support/build.gradle.kts @@ -1,4 +1,5 @@ dependencies { + implementation(("io.micrometer:micrometer-tracing")) implementation("org.mockito:mockito-core") implementation("org.springframework.boot:spring-boot-autoconfigure") implementation("org.springframework.boot:spring-boot-cache") diff --git a/server/libs/platform/platform-component/platform-component-test-int-support/src/main/java/com/bytechef/platform/component/test/config/ComponentTestIntConfiguration.java b/server/libs/platform/platform-component/platform-component-test-int-support/src/main/java/com/bytechef/platform/component/test/config/ComponentTestIntConfiguration.java index 19fc163e33e..ea65a276bd0 100644 --- a/server/libs/platform/platform-component/platform-component-test-int-support/src/main/java/com/bytechef/platform/component/test/config/ComponentTestIntConfiguration.java +++ b/server/libs/platform/platform-component/platform-component-test-int-support/src/main/java/com/bytechef/platform/component/test/config/ComponentTestIntConfiguration.java @@ -39,6 +39,7 @@ import com.bytechef.platform.file.storage.TempFileStorage; import com.bytechef.platform.file.storage.TempFileStorageImpl; import com.bytechef.platform.workflow.execution.accessor.JobPrincipalAccessorRegistry; +import io.micrometer.tracing.Tracer; import java.util.Collections; import java.util.List; import java.util.Map; @@ -129,6 +130,11 @@ JobPrincipalAccessorRegistry jobPrincipalAccessorRegistry() { return new JobPrincipalAccessorRegistry(List.of()); } + @Bean + Tracer tracer() { + return Mockito.mock(Tracer.class); + } + @Bean TaskFileStorage workflowFileStorageFacade() { return new TaskFileStorageImpl(new Base64FileStorageService()); diff --git a/settings.gradle.kts b/settings.gradle.kts index 3c8ba1a7fec..e77b0569171 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -347,9 +347,10 @@ include("server:libs:modules:components:file-storage") include("server:libs:modules:components:filesystem") include("server:libs:modules:components:firecrawl") include("server:libs:modules:components:form") -include("server:libs:modules:components:ftp") include("server:libs:modules:components:freshdesk") include("server:libs:modules:components:freshsales") +include("server:libs:modules:components:ftp") +include("server:libs:modules:components:gaurus") include("server:libs:modules:components:github") include("server:libs:modules:components:gitlab") include("server:libs:modules:components:google:google-bigquery") @@ -673,3 +674,5 @@ include("server:ee:libs:platform:platform-workflow:platform-workflow-worker:plat include("server:ee:libs:modules:components:api-platform") include("server:ee:libs:modules:components:app-event") include("server:ee:libs:modules:components:code-workflow") + +include("server:libs:modules:components:gaurus")