/**
* @name Security
* @description This module exposes functions
* related to security procedures.
*
* @module security
**/
import NodeRSA from 'node-rsa'
import Promise from 'bluebird'
import qs from 'qs'
import {
toString,
replace,
pipe,
} from 'ramda'
import {
verifySignature,
calculateSignature,
} from '../postback'
import transactions from './transactions'
const cleanNumber = pipe(
toString,
replace(/[^0-9]/g, '')
)
const queryString = card =>
qs.stringify({
card_number: cleanNumber(card.card_number),
card_holder_name: card.card_holder_name,
card_expiration_date: cleanNumber(card.card_expiration_date),
card_cvv: cleanNumber(card.card_cvv),
})
const generateCardHash = ({ public_key: publicKey, id }, cardString) => {
const key = new NodeRSA(publicKey, {
encryptionScheme: 'pkcs1',
})
const encrypted = key.encrypt(cardString, 'base64')
const cardHash = `${id}_${encrypted}`
return cardHash
}
/**
* Encrypt a card object into a card_hash
*
* @param {Object} opts An options params which
* is usually already bound
* by `connect` functions.
*
* @param {Object} card The card object.
* {@link https://pagarme.readme.io/v1/reference#gerando-card_hash-manualmente|API Reference for this payload}
*
* @param {String} card.card_number The card's number.
* Example: '4111111111111111'
* @param {String} card.card_holder_name The card's holder name.
* Example: 'Pedro Paulo'
* @param {String} card.card_expiration_date The card's expiration date.
* Example: '1225' or '12/25'
* @param {String} card.card_cvv The card's cvv.
* Example: '543'
*/
const encrypt = (opts, card) =>
Promise.props({
key: card.key ? card.key : transactions.cardHashKey(opts),
cardString: queryString(card),
})
.then(({ key, cardString }) => generateCardHash(key, cardString))
/**
* Generates a hash signed with your api_key.
* This is used mainly to validate postbacks,
* this functions is the same as pagarme.postback.calculatesignature
* but it already knows your api_key.
*
* @param {Object} opts An options params which
* is usually already bound
* by `connect` functions.
*
* @param {String} string The string to be hashed.
*
*/
const sign = (opts, string) =>
calculateSignature(opts.body.api_key, string)
/**
* Verifies a hash signed with your api_key.
* This is used mainly to validate postbacks,
* this functions is the same as pagarme.postback.validateSignature
* but it already knows your api_key.
*
* @param {Object} opts An options params which
* is usually already bound
* by `connect` functions.
*
* @param {String} string The string to be hashed.
*
* @param {String} expected The expected result.
*
*/
const verify = (opts, string, expected) =>
verifySignature(opts.body.api_key, string, expected)
export default {
encrypt,
sign,
verify,
}
|