V2 Securely Uploading .p7m file(s)

POST /api/v2/presigned-url (IN PROGRESS)

The /api/v2/presigned-url endpoint of the Cauzioni Smart platform is designed to facilitate the secure upload of digitally signed files for guarantees. This endpoint generates a presigned URL, allowing for a direct and secure file upload to the platform’s storage solution without exposing sensitive credentials or storage details.

Purpose

Before creating a digital guarantee, the signed document must be uploaded to the Cauzioni Smart platform. This endpoint automates the generation of a secure, temporary URL for this purpose. It streamlines the process, ensuring both security and efficiency in handling the digital guarantees.

Requesting a Presigned URL

To generate a presigned URL for uploading a file, send a POST request to the /api/v2/presigned-url endpoint. This request must include the Authorization header with your API key and a JSON payload specifying the type of file you intend to upload. The Content-Type header should be set to application/json to indicate the nature of the request body.

Headers:

  • Authorization: YOUR_API_KEY

Request Body:

The request body must include a fileType field specifying the type of the file. For example, to generate a presigned URL for a p7m file, the fileType should be set to p7m.

Moreover you have to specify if the document is public or not, because in some cases backend will verify the file structure for the file uploaded (like p7m).

{
  "fileType": "p7m", "isDocumentPublic": false
}

Response

The response from this endpoint includes the presigned URL, additional required fields for the upload, the file type, and the key associated with the upload session. Below is a description of each component in the response:

  • presignedUrl: The URL to which the file should be uploaded.
  • fields: Additional fields required by the storage service to accompany the upload request.
  • fileType: Indicates the type of file that is expected to be uploaded. In the production environment, this will always be .p7m.
  • key: The unique identifier for the uploaded file in the storage system. This parameter value is used in another API to verify file status

The key parameter can be used to monitor the file status. All files that we’ll upload in the system will be analyzed by Antivirus and in some cases, in according to the value of isDocumentPublic they will be verified: for example pdf end p7m will be verified with structure control, because in that case they must have got a sign.

Example Response

{
  "statusCode": 200,
  "body": {
    "presignedUrl": "https://example-url.com/upload",
    "fields": {
      "Policy": "xyz",
      "X-Amz-Algorithm": "AWS4-HMAC-SHA256"
    },
    "fileType": ".p7m",
    "key": "unique-file-key"
  },
  "headers": {
    "Content-Type": "application/json"
  }
}

File Upload Requirements

Staging and Production Environment are configured in the same way. The types of files that can be uploaded are JPEG, PNG, PDF, P7M, TSD and M7M.

We can distinguish the following cases:

  • public document false: all types listed before are supported, but API provides warning information about no compliant file structure for p7m, tsd and m7m formats;
  • public document true: PDF, P7M, are accepted but the API verify correctness of file structure.

A file can be blocked because it is infected by a virus or it is blocked because it is declared public but the file structure or format isn’t compliant.

Uploading a File

Once you receive the presigned URL and additional fields, you can proceed to upload your file. Ensure the file type meets the environment-specific requirements to prevent any errors during the upload process.

For detailed instructions on how to upload files using a presigned URL, refer to the AWS S3 documentation on presigned URLs.

JavaScript Example Using Axios

const formData = new FormData();

// Assuming 'data' is the response from the `/api/v1/presigned-url` or /api/v2/presigned-url endpoint
Object.keys(data.fields).forEach((key) => {
  formData.append(key, data.fields[key]);
});

// Append the file to be uploaded with the key 'file'
formData.append('file', file); // 'file' is your file object

await axios.post(data.presignedUrl, formData, {
  headers: { 'Content-Type': 'multipart/form-data' }
});

In this example, data represents the JSON response received from the presigned URL endpoint, and file is the file object you wish to upload. This method involves iterating over the fields provided in the response and appending them to a FormData object along with the file.

cURL Example

To upload a file using cURL, you need to construct a similar multipart/form-data request. Here’s an example based on the fields and presigned URL received:

curl -X POST 'PRESIGNED_URL_RECEIVED_FROM_API' \
  -F 'key=VALUE_FROM_FIELDS' \
  -F 'X-Amz-Algorithm=VALUE_FROM_FIELDS' \
  -F 'X-Amz-Credential=VALUE_FROM_FIELDS' \
  -F 'X-Amz-Date=VALUE_FROM_FIELDS' \
  -F 'Policy=VALUE_FROM_FIELDS' \
  -F 'X-Amz-Signature=VALUE_FROM_FIELDS' \
  -F 'file=@/path/to/your/file.jpeg' \
  -H 'Content-Type: multipart/form-data'    

During and after file uploading you can verify file status with /api/v2/file-status API.

GET /api/v2/file-status?fileKey={{Key}}(IN PROGRESS)

Key is a unique identifier for the file uploaded and it is used to monitor its status after presigned upload, because the backend will verify virus presences and fie structure correctness if necessary.

Possible values for file status are:

  • CLEAN the file can be processed, ha passed all kind of validations
  • IN PROGRESS the antivirus or structure processing is in progress
  • INFECTED the file contains some viruses, it can’t be used and will be removed as soon as possible
  • ERROR SIGNED the file doesn’t contain a sign as requested (depend on isDocumentPublic flag)

Example Response

{"status":"CLEAN","warning":"WARNING","signer":""}

JavaScript Example Using Axios

import axios from "axios";

async function checkFileStatus(key) { 
  const url = '/api/v2/file-status?fileKey='+key;
  try { 
    const response = await axios.get(url); 
    return response.data.status; 
  } catch (err) { 
    console.error("Error:", err.message);
    return "ERROR SIGN"; // fallback 
  } 
}

async function pollFileStatus(key, interval = 2000) { 
  let status = "IN PROGRESS";
  while (status === "IN PROGRESS") { 
    status = await checkFileStatus(key); 
    console.log("Stato attuale:", status);
    if (status === "IN PROGRESS") {
      await new Promise((resolve) => setTimeout(resolve, interval));
    }
  } 
  return status; 
}