Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
@journeyapps/cc-util-data
Advanced tools
Simplified Journey JSON Data for better use with Handlebars and PDF document generation
The purpose of this module is to enable Journey Apps cloud code to easily generate a json payload for use in PDF/Excel reports.
Normally you would manually get all the data before you add it to a handlebars template or a Excel report. To overcome this, this module exists. Its sole purpose is to easily gather the data for your PDF or Excel report without any hassles.
As a added benefit, you can also upload your PDF to the backend for reference at a later stage.
All code is clearly documented, please see code for more details. View an example below.
yarn add @journeyapps/cc-util-data --save
yarn add @journeyapps/cc-util-data
yarn version
This might not be apparent at the very start, but there is a specific way of using this to retrieve the correct data.
The main function fetchData
has 3 parameters:
/**
* Retrieves the Data of the object with its children.
* @param {string} ObjectID ID of the main object, the main object is the model
* @param {string} model The Entry model name. Found in <model name="<here>" label="label">
* @param {array} relatedModels Array of related models by name. Found in <has-many model="<here second>" name="<here first>" /> or <belongs-to model="<here second>" name="<here first>" />
* @return {JSON} JSON object representing the data
*/
async fetchData(objectID, model, relatedModels) { ... }
/**
* Uploads a Attachment to the backend.
* @param {JourneyAttachment} attachment Journey Apps attachment object
* @param {Object} object Destination Object for upload
* @param {String} [field="generated_report"] Field to upload to, defaults to generated_report
*/
async uploadAttachment(attachment, object, field = "generated_report") {
It is extremely important to use the name of the relationships and only the model name as a fallback. The related models do not include the main model as this is derived.
Example fetchData:
let _ccUtilData = new ccUtilData(this.backend); //Pass in the backend object (The tokens live in here)
await _ccUtilData.fetchData('87cbe05a-904a-4255-b020-dd9d9ccedc3e', 'hotel',['rooms', 'rooms.bookings']);
await _ccUtilData.fetchData('87cbe05a-904a-4255-b020-dd9d9ccedc3e', 'booking',['room', 'room.hotel']);
Notice the difference between a hotel has_many rooms vs a booking belongs_to a room.
Example uploadAttachment:
let _ccUtilData = new ccUtilData(this.backend); //Pass in the backend object (The tokens live in here)
let _hotel = DB.hotel.first();
let _attachmentContent = await _hotel.broshure.toBase64();
let _attachment = {
content: _attachmentContent,
filename: "test.pdf"
}
let _object = DB.hotel.first('87cbe05a-904a-4255-b020-dd9d9ccedc3e');
await _data.uploadAttachment(_attachment, _object, 'broshure');
When accessing the Data Model of the current environment the Cloud Code task is running in, we only need to pass in the this.backend
object, which contains all the config cc-util-data
requires.
index.js:
// make sure config.js has the relevant credentials
const config = require('./config');
const ccUtilData = require('@journeyapps/cc-util-data');
export async function run() {
const _options = {
validateMediaUploaded: true
};
let _ccUtilData = new ccUtilData(this.backend); //Pass in the backend object (The tokens live in here)
var _data = await _ccUtilData.fetchData('87cbe05a-904a-4255-b020-dd9d9ccedc3e', 'hotel',['rooms', 'rooms.bookings']);
//Do something with the data
}
You have the ability to pass in some options, these define some behavior of the module. Below are the defaults.
/**
* Default options used by the util data
* @type {Object}
*/
const DEFAULT_OPTIONS = {
/**
* If true, signatures and photos will be validate for state=uploaded
* @type {Boolean}
*/
validateMediaUploaded?: true,
/**
* If true, the util wil auto download the images that it finds.
* @type {Boolean}
*/
preloadImages?: false,
/**
* Sets the default image to pre download
* @type {string} original | fullscreen | thumbnail
*/
preloadImageSize?: 'fullscreen',
/**
* Set the format to download the pre image in
* @type {string} buffer | base64
*/
preLoadImageFormat?: 'buffer',
/**
* Sets to false to hide all the logs that get printed
* @type {boolean}
*/
printLogs?: true,
/**
* Enable sorting of json result for easier navigation
*/
sorting?: true,
/**
* Items to sort to the top of the list
*/
sortToTop?: ['id', 'type', 'display']
/**
* Disables batch fetching in order to allow custom skipping in has many queries
* (Limit query parameters are required to keep queries smaller than 1000 objects)
*/
disableBatchFetching?: boolean
};
A special flag ready
gets added on every (not null) photo or signature field that can be used in handlebars to check if the signature has been uploaded. A signature can be directly reference by using a img object and passing in the URL. The PDF document compiler takes care of the rest.
{{#if signature}}
<div class="signature">
{{#if signature.ready}} <img class="img-responsive" src="{{signature.original}}"> {{/if}}
</div>
{{/if}}
You are able to preload images by setting the option flat preloadImages
. You can also retrieve the images afterwards the same way you can with JourneyApps DB.
Note, preloadImages
will fail if the image is not ready.
let _d = await _data.fetchData('6e59d067-7d41-4b7b-8794-d9de46b3a2b4', 'room');
// Original
let _url = await _d.photo.url;
let _buffer = await _d.photo.toBuffer();
let _base64 = await _d.photo.toBase64();
// Fullscreen
let _url = await _d.photo.fullscreen.url;
let _buffer = await _d.photo.fullscreen.toBuffer();
let _base64 = await _d.photo.fullscreen.toBase64();
// Thumbnail
let _url = await _d.photo.thumbnail.url;
let _buffer = await _d.photo.thumbnail.toBuffer();
let _base64 = await _d.photo.thumbnail.toBase64();
has_many
relationshipWhen dealing with a has_many
relationship, you might only want to get the object with specific values.
The queries are placed at the end of a related object between {
and }
. They only work for has_many
relationships and can contain anything you can use with the Backend API. See https://docs.journeyapps.com/reference#api-querying-objects
// make sure config.js has the relevant credentials
const config = require('./config');
const ccUtilData = require('@journeyapps/cc-util-data');
export async function run() {
let _ccUtilData = new ccUtilData(this.backend); //Pass in the backend object (The tokens live in here)
//Get bookings where the price is greater than 300
let _data = await _ccUtilData.fetchData('87cbe05a-904a-4255-b020-dd9d9ccedc3e', 'hotel',['rooms', 'rooms.bookings{q[price.gt]=300}']);
//Get all the bookings for the family room
_data = await _ccUtilData.fetchData('87cbe05a-904a-4255-b020-dd9d9ccedc3e', 'hotel',['rooms{q[name]=Family}', 'rooms.bookings']);
//Do something with the data
}
We can specify a custom environment by explicitly adding the url
, username
and password
to the configuration.
config.js:
// KitchenSink Credentials used
let config = {
url: 'https://run-testing-us.journeyapps.com/api/v4/5989b1c2ecc8cf019e5d3db0',
username: '<USERNAME>',
password: '<PASSWORD>'
}
OR
let config = {
url: 'https://run-testing-us.journeyapps.com/api/v4/5e981f8e076011390e571e79',
authorization: 'Bearer <TOKEN>'
}
index.js:
// make sure config.js has the relevant credentials
const config = require('./config');
const ccUtilData = require('@journeyapps/cc-util-data');
export async function run() {
let _ccUtilData = new ccUtilData(config); //Pass in the custom config containing the credentials
var _data = await _ccUtilData.fetchData('87cbe05a-904a-4255-b020-dd9d9ccedc3e', 'hotel',['rooms', 'rooms.bookings']);
//Do something with the data
}
See the LICENSE file.
FAQs
Simplified Journey JSON Data for better use with Handlebars and PDF document generation
We found that @journeyapps/cc-util-data demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.