Время создания
Filters

Hi there, here is a question I am not sure on how to set it up.

I want to add a user to our platform that can work with all the basic features but has limited access to our entire customer database. This means, he/she can only see the accounts and customers we put in a specified group.

How do I set this up? Or is there an example somewhere i can follow?

Like 0

Like

0 comments
Show all comments

Hi all,

i'm trying to setup a backend system able to send push notification to mobile app (not developed in creatio) through FCM rest API.

The first hurdle is obtaining a valid token to authenticate to notification api exposed by firebase. In order to obtain this token i do have to call another rest api passing a jwt token generated by me and signed by a private key downloaded from fcm.

I've got a code (pasted below) that manages to generate this encrypted token and it's working in visual studio. But if i try to use it in a script task i got the exception 

'RSA' does not contain a definition for 'ImportPkcs8PrivateKey' and no accessible extension method 'ImportPkcs8PrivateKey' accepting a first argument of type 'RSA' could be found (are you missing a using directive or an assembly reference?)

As far as i know this exception is thrown if .net core being used is version 5 or below. But i'm on a demo instance with creation 8.2.0.4183 which should be already using net core 6 right?

Do you have any suggestion? (the flow is already configured to import System.Security.Cryptography)

 

 

--code--

   var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
var header = new Dictionary
       {
           { "alg", "RS256" },
           { "typ", "JWT" }
       };
string headerJson = JsonConvert.SerializeObject(header);
string encodedHeader = Convert.ToBase64String(Encoding.UTF8.GetBytes(headerJson)).TrimEnd('=').Replace('+', '-').Replace('/', '_');

var payload = new Dictionary
       {
           { "iss", CLIENT_EMAIL },
           { "scope", SCOPE },
           { "aud", TOKEN_URI },
           { "iat", now },
           { "exp", now + 3600 }
       };
string payloadJson = JsonConvert.SerializeObject(payload);
string encodedPayload = Convert.ToBase64String(Encoding.UTF8.GetBytes(payloadJson)).TrimEnd('=').Replace('+', '-').Replace('/', '_');
string unsignedJwt = $"{encodedHeader}.{encodedPayload}";
byte[] dataBytes = Encoding.UTF8.GetBytes(unsignedJwt);

// Decode PEM -> PKCS#8 bytes
string cleanKey = PRIVATE_KEY
   .Replace("-----BEGIN PRIVATE KEY-----", "")
   .Replace("-----END PRIVATE KEY-----", "")
   .Replace("\\n", "\n")  // ← decodifica reale da stringa JSON
   .Trim();


byte[] privateKeyBytes = Convert.FromBase64String(cleanKey);

// Firma con RSA-SHA256
byte[] signature;
using (var rsa = RSA.Create())
{
   rsa.ImportPkcs8PrivateKey(privateKeyBytes, out _);
   signature = rsa.SignData(dataBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
string encodedSignature = Convert.ToBase64String(signature)
   .TrimEnd('=').Replace('+', '-').Replace('/', '_');

string jwt = $"{unsignedJwt}.{encodedSignature}";


return true;

Like 1

Like

1 comments

Hi Roberto,

In the cloud-based demo version of Creatio (including your current instance), the Script Task in business processes runs under .NET Framework 4.7.2. This limitation is specific to the cloud version. If you run Creatio on-premises, it's possible to configure and run business logic under .NET Core instead.

As a result, the method ImportPkcs8PrivateKey() is not available in the cloud version. Other types like RSASignaturePadding, HashAlgorithmName, and RSA.Create() are also unavailable in this context.

Recommended Solution:
Move JWT generation to an external service
- Create a small Web API (in .NET 6 or above).
- Let it generate and return the signed JWT token.
- Call it from Creatio using HTTP request.

Show all comments

Hi,

In Contact Object, there is a multiselect field 'Affiliation' where I add any no of item from list.

Source Code:

 

Query: Whenever user click on 'x' icon to delete an item from multiselect field, Creatio should pop up a confirmation box i.e. 'Do you want to remove Item' & then delete item if user agree.

 

 

Like 0

Like

0 comments
Show all comments

Has anyone discovered yet if there is a shorter url that redirects to the app hub? Similar to how you can use [creatiourl]/0/dev to open the configuration or [creatiourl]/0/flags to open features?

I really would love a quick & easy url like that to open the app hub. Does one exist?

Like 5

Like

0 comments
Show all comments

Hello,

I created a validation for telephone numbers as explained in this article: Implement the validation of a field value on a page | Creatio Academy
For testing purposes, I added it to the notes field on the contacts form, and it works fine.


However, I want to add the validation to the communications options on the left side of the form.
How do I bind the validation in the viewModelConfigDiff?
Also, only communication options of type "phone number" should be validated.

 

Thanks,

Robert

Like 1

Like

3 comments

Hello,

Currently there is no way to add the validator using the regular approach with the validators property on the schema. However you can try adding it using the formControl for the ContactCommunicationOptionsItems (but note that this will be applied for phones, email, skype and web (in other words for all communication options)).

 

How to add the validator using formControl:

 

  1. Implement the same validator on some separate field on the page
  2. Find this validator in the context of the crt.HandleViewModelAttributeChangeRequest request execution (like request.$context._validators["AccountAccountCategory_List.value"][0]), but replace AccountAccountCategory_List.value with your attribute name on the page to which the validator is added. Also make sure array with only one element is returned (since you can have several validators for the same field and the array of validators can contain more than 1 element thus ...["AccountAccountCategory_List.value"][0] can return another validator.
  3. In the context of the crt.HandleViewModelAttributeChangeRequest request (connected to the change of the ContactCommunicationOptionsItems attribute) add the following code:

request.$context.getControl("ContactCommunicationOptionsItems").formControl.addValidators(request.$context._validators["AccountAccountCategory_List.value"][0])
 

But replace equest.$context._validators["AccountAccountCategory_List.value"][0] with the needed validator.

 

This is the only way to add the validator for this CommunicationOptions component (but once again note that this will be added to all the other communication options). 

Oleg Drobina,

thank you for pointing me in the right direction!

However, I can't get it to run...I used the following code, but the validation won't be triggered:

			{
			    request: "crt.HandleViewModelAttributeChangeRequest",
			    handler: async (request, next) => {
					if (request.attributeName === 'ContactCommunicationOptionsItems') {
						const validators = request.$context._validators;
						const telValidator = validators["StringAttribute_cuzyv0b"]?.[0];
						if (telValidator) {
							request.$context.getControl("ContactCommunicationOptionsItems").formControl.addValidators(telValidator);	
						}
					}					
			        return true;
			    }
			}

What's also strange is that when the handler is executed again (after I changed the field value), all properties of the formControl related to validation (asyncValidator, validator, _rawValidators, _rawAsyncValidators) are empty again!

Any idea what could go wrong here?

Thanks,

Robert

 

Robert Pordes,

Unfortunately no, this was the way I used locally and that worked and maybe the difference may arrise in the application version that was used for tests (8.2.2 in my case) or in other handlers maybe. This should be debugged only, there is no other way to identify what's wrong.

Show all comments