- Home [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
- Getting started
- Manage types
- Global context and isolation
- Manage apps
- Batch actions with app items
- Manage external services
- Scripts in widgets
- Web components
- Access permissions
- Getting started with processes
- Getting started with signatures
- Getting started with file previews
- Getting started with the organizational chart
- Getting started with users and groups
-
Getting started with the
Table data type - Dynamic calculation of event type
- Use cases
- How to set up custom view of app items
- How to set up dynamic display of fields and widgets with a complex condition
- How to register a document
- How to calculate the number of days between two dates
- How to create a substitution for a user
- How to use pagination and sorting when searching for app items
- API
- Object types
- Data types
- Global constants
- Work with apps
- Web requests
- Access permissions
- Document flow
- Live Chats
- “Code” widget
- Signatures
- Business calendars
- Integration with IP telephony
- Integration with email marketing services
In this article
Getting started with signatures
The system offers modules to work with some cryptographic service providers (CSPs) that allow you to sign user data. The default providers include CryptoPro and NCA. Client scripts help you sign data using other cloud CSPs. To work with these features, you need to configure a digital signature in an app.
Internal signature
To get specific data and manage changes in the system, you can sign data using an internal signature. A signature of this type is not legally valid; it is used specifically to control changes in an app and capture a version of data stored in an app item. Along with the signature, you can obtain data calculated based on an app’s signature settings. With an internal signature, you can sign attributes of an item of any app type or a file in a Document type app. To get an internal signature, you need to store the app in the context or find it using the Global or Namespace objects:
async function workWithDataSigns(): Promise<void> { // Getting the app from the context // `document` is a Document type app const app = Context.data.document!; // Getting the app’s data const appData = await app.fetch(); // Getting signatures const innerSigns = await appData.getDataSigns(); // Getting the attributes’ internal signature to sign the data using a CSP const attributesInnerSign = innerSigns.find(innerSign => innerSign.type === SignType.Attributes); if (!attributesInnerSign) { throw new Error('Internal signature not found'); } }
Upload an obtained signature to the system
In the previous example, we signed an app item’s attributes. Each internal digital signature stores the data’s hash (data footprint) and the signed data itself. This data can then be used to send it to the CSP that signs it:
async function saveSign(): Promise<void> { // `SignProvider` is an example of a CSP // Includes one method of calculating a signature using the data const signProvider = new SignProvider(); // Getting a signature for an app item’s attributes const signData = signProvider.sign(attributesInnerSign.body); const newSign: NewSign = { // Signature in the base64 format sign: signData; // Type of signature, depending on what needs to be signed, `signature` or `files` signType: attributesInnerSign.type; // Code of the signature provider codeProvider: 'signProvider'; // ID of the base64 file body: attributesInnerSign.body, // Hash of the signed data (it is needed to identify the version of the signed data) hash: attributesInnerSign.hash, } await appData.uploadSign(newSign); }
Get the signed attributes and the signature as a file
To get the content of the signed attributes and the signature itself, you the createAttributesFile and EntitySign.createSignFile methods. To get EntitySign, you need the history of app item signatures. To find the necessary version of the signature in the history, use the app’s internal signature:
async function getSignsFiles(): Promise<void> { // Getting a Document type app from the context of the client script const app = Context.data.document!; // Getting the app’s data const appData = await app.fetch(); // Getting the history of an app item’s signatures const signsHistory = await appData.getSignHistory(); // Getting internal signatures const innerSigns = await appData.getDataSigns(); // Let’s add the attributes’ internal signature to sign the data using a CSP const attributesInnerSign = innerSigns.find(innerSign => innerSign.type === SignType.Attributes); if (!attributesInnerSign) { throw new Error('Internal signature not found'); } // Let’s find the signatures of the last version of an app item in the signatures archive const signs = signsHistory.find(signs => signs.hash === attributesInnerSigns.hash); if (!signs) { throw new Error('This version is not signed'); } const dataSign = signs.signs[0]; const attributesFile = await dataSign.createAttributesFile(); const signFile = await dataSign.createSignFile(); }
Get detailed information about a signature
The system allows you to get detailed information about a signature, including:
To get the information, call the EntitySign.getDetails method. This method allows you to get detailed information about a signature. Let’s say we need to define whether data was signed by an individual or a legal entity. To do that, we need to get the signature from the history and call the EntitySign.getDetails method. After obtaining the data, we need to analyze the content of the certificate:
async function whoMadeSign(): Promise<void> { // Getting a Document type app from the context of a client script const app = Context.data.document!; // Getting the app’s data const appData = await app.fetch(); // Getting the history of an app’s signatures const signsHistory = await appData.getSignHistory(); // Getting the most recent signature const sign = signsHistory[0].signs[0]; // Getting information about the signature const signDetails = await sign.getDetails(); // If one of the following fields is filled out, the data is signed by a legal entity // Other fields of a certificate can also be used for checks of this type, // depending on the provider who issued the digital signature const orgField = signDetails.subject['O'] || signDetails.subject['OU']; if (orgField !== '') { // Signed by a legal entity } else { // Signed by an individual } }
You can also obtain information about signature certificates, including data about the issuing CA, the entity to whom the certificate was issued, and its validity period.
Here’s an example script to retrieve information about signature certificates expiring within a month:
async function signWithSoonExpiredCerts (): Promise<void> { // Get current user const user = await System.users.getCurrentUser(); // Date the signature certificate expires const expiredDate = new Datetime().addDate(0, 1, 0); // Get the user’s signatures const digitalSigns = await System.signs.digitalSigns.search().where(sign => sign.__createdBy.eq(user)).all(); // Get signatures with certificates expiring within the next month const expiredSigns = digitalSigns.filter(sign => sign.data.validUntilAt?.beforeOrEqual(expiredDate)); // Write information about signatures with expiring certificates to the context Context.data.expiredcerts = 'Certificates expiring within a month: '; for (let sign of expiredSigns) { const subjectName = sign.data.subject ? sign.data.subject['CN'] ?? 'name unknown' : 'signer unknown'; Context.data.expiredcerts += `${sign.id} : ${subjectName},`; } return; }