UNPKG

@govtechsg/open-attestation

Version:
114 lines (113 loc) 4.32 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.unsaltData = exports.saltData = exports.unsalt = exports.uuidSalt = exports.typedStringToPrimitive = exports.primitiveToTypedString = exports.deepMap = void 0; var lodash_1 = require("lodash"); var isUUID_1 = __importDefault(require("validator/lib/isUUID")); var uuid_1 = require("uuid"); var UUIDV4_LENGTH = 37; var PRIMITIVE_TYPES = ["string", "number", "boolean", "undefined"]; /* eslint-disable no-use-before-define */ /** * Curried function that takes (iteratee)(value), * if value is a collection then recurse into it * otherwise apply `iteratee` on the primitive value */ var recursivelyApply = function (iteratee) { return function (value) { if ((0, lodash_1.includes)(PRIMITIVE_TYPES, typeof value) || value === null) { return iteratee(value); } return (0, exports.deepMap)(value, iteratee); // eslint-disable-line @typescript-eslint/no-use-before-define }; }; /** * Applies `iteratee` to all fields in objects, goes into arrays as well. * Refer to test for example */ var deepMap = function (collection, iteratee) { if (iteratee === void 0) { iteratee = lodash_1.identity; } if (collection instanceof Array) { return (0, lodash_1.map)(collection, recursivelyApply(iteratee)); } if (typeof collection === "object") { return (0, lodash_1.mapValues)(collection, recursivelyApply(iteratee)); } return collection; }; exports.deepMap = deepMap; /* eslint-enable no-use-before-define */ // disabling this because of mutual recursion var startsWithUuidV4 = function (input) { if (input && typeof input === "string") { var elements = input.split(":"); return (0, isUUID_1.default)(elements[0], 4); } return false; }; /** * Detects the type of a value and returns a string with type annotation */ function primitiveToTypedString(value) { switch (typeof value) { case "number": case "string": case "boolean": case "undefined": return "".concat(typeof value, ":").concat(String(value)); default: if (value === null) { // typeof null is 'object' so we have to check for it return "null:null"; } throw new Error("Parsing error, value is not of primitive type: ".concat(value)); } } exports.primitiveToTypedString = primitiveToTypedString; /** * Returns an appropriately typed value given a string with type annotations, e.g: "number:5" */ function typedStringToPrimitive(input) { var _a = input.split(":"), type = _a[0], valueArray = _a.slice(1); var value = valueArray.join(":"); // just in case there are colons in the value switch (type) { case "number": return Number(value); case "string": return String(value); case "boolean": return value === "true"; case "null": return null; case "undefined": return undefined; default: throw new Error("Parsing error, type annotation not found in string: ".concat(input)); } } exports.typedStringToPrimitive = typedStringToPrimitive; /** * Returns a salted value using a randomly generated uuidv4 string for salt */ function uuidSalt(value) { var salt = (0, uuid_1.v4)(); return "".concat(salt, ":").concat(primitiveToTypedString(value)); } exports.uuidSalt = uuidSalt; /** * Value salted string in the format "salt:type:value", example: "ee7f3323-1634-4dea-8c12-f0bb83aff874:number:5" * Returns an appropriately typed value when given a salted string with type annotation */ function unsalt(value) { if (startsWithUuidV4(value)) { var untypedValue = value.substring(UUIDV4_LENGTH).trim(); return typedStringToPrimitive(untypedValue); } return value; } exports.unsalt = unsalt; // Use uuid salting method to recursively salt data var saltData = function (data) { return (0, exports.deepMap)(data, uuidSalt); }; exports.saltData = saltData; var unsaltData = function (data) { return (0, exports.deepMap)(data, unsalt); }; exports.unsaltData = unsaltData;