UNPKG

@iexec/dataprotector-deserializer

Version:
168 lines 7.77 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.IExecDataProtectorDeserializer = void 0; const promises_1 = require("fs/promises"); const path_1 = require("path"); const borsh_1 = require("borsh"); const jszip_1 = __importDefault(require("jszip")); /** * Helper class to deserialize a protected data in trusted iApp * * Usage: * * ```js * const dataprotectorDeserializer = new IExecDataProtectorDeserializer(); * * const value1 = await dataprotectorDeserializer.getValue("path.to.value1", "bool"); * const value2 = await dataprotectorDeserializer.getValue("path.to.value2", "string"); * ``` * * Options: * * - `mode`: specify the deserialization mode (default `"optimistic"`) * - `"borsh"` for current protected data * - `"legacy"` for protected data created with `@iexec/dataprotector@0` * - `"optimistic"` try both * - `protectedDataPath`: overrides the dataset path, by default use the standard dataset path provided in the iExec worker runtime */ class IExecDataProtectorDeserializer { constructor(options) { this.mode = (options === null || options === void 0 ? void 0 : options.mode) || 'optimistic'; if (options === null || options === void 0 ? void 0 : options.protectedDataPath) { this.protectedDataPath = options === null || options === void 0 ? void 0 : options.protectedDataPath; } else if (process.env.IEXEC_DATASET_FILENAME && process.env.IEXEC_IN) { this.protectedDataPath = (0, path_1.join)(process.env.IEXEC_IN, process.env.IEXEC_DATASET_FILENAME); } if (this.protectedDataPath) { this.zipPromise = (0, promises_1.readFile)(this.protectedDataPath).then((buffer) => { return new jszip_1.default().loadAsync(buffer); }); this.zipPromise.catch(() => { /* prevents unhandled promise rejection */ }); } } /** * Deserializes the value at a given `path` with the value `schema` * * Params: * * - `path`: path to the desired value in the data object * - `schema`: schema of the desired data (see list ) * * | schema | deserializes to | * | ---|---| * | `"bool"` | `boolean` | * | `"f64"` | `number` | * | `"i128"` | `bigint` | * | `"string"` | `string` | * | `"boolean"` (legacy schema) | `boolean` | * | `"number"` (legacy schema) | `number` | * | any other value | `Uint8Array` | * * Usage: * * ```js * const value = await dataprotectorDeserializer.getValue("path.to.string.value", "string"); * ``` */ getValue(path, schema) { var _a; return __awaiter(this, void 0, void 0, function* () { if (this.zipPromise === undefined) { throw Error('Missing protected data'); } const zip = yield this.zipPromise.catch(() => { throw Error('Failed to load protected data'); }); const serialized = yield ((_a = zip .file(path.split('.').join('/'))) === null || _a === void 0 ? void 0 : _a.async('uint8array')); if (!serialized) { throw Error(`Failed to load path ${path}`); } switch (schema) { case 'bool': case 'i128': case 'f64': if (this.mode === 'legacy') { throw Error(`Unsupported schema "${schema}" in "${this.mode}" mode`); } try { // eslint-disable-next-line @typescript-eslint/no-explicit-any return (0, borsh_1.deserialize)(schema, serialized); } catch (e) { throw Error(`Failed to deserialize "${path}" as "${schema}" in "${this.mode}" mode`); } case 'string': try { if (this.mode === 'legacy') { // eslint-disable-next-line @typescript-eslint/no-explicit-any return Buffer.from(serialized).toString('utf8'); } try { // try borsh deserialization first // eslint-disable-next-line @typescript-eslint/no-explicit-any return (0, borsh_1.deserialize)(schema, serialized); } catch (e) { if (this.mode === 'optimistic') { // fallback to legacy // eslint-disable-next-line @typescript-eslint/no-explicit-any return Buffer.from(serialized).toString('utf8'); } throw e; } } catch (e) { // avoid sensitive information leakage in error throw Error(`Failed to deserialize "${path}" as "${schema}" in "${this.mode}" mode`); } case 'number': if (this.mode === 'borsh') { throw Error(`Unsupported schema "${schema}" in "${this.mode}" mode`); } try { // eslint-disable-next-line @typescript-eslint/no-explicit-any return Number(Buffer.from(serialized).toString()); } catch (e) { // avoid sensitive information leakage in error throw Error(`Failed to deserialize "${path}" as "${schema}" in "${this.mode}" mode`); } case 'boolean': if (this.mode === 'borsh') { throw Error(`Unsupported schema "${schema}" in "${this.mode}" mode`); } try { // legacy serialization spec for 'boolean' matches borsh spec 'bool' // eslint-disable-next-line @typescript-eslint/no-explicit-any return (0, borsh_1.deserialize)('bool', serialized); } catch (e) { // avoid sensitive information leakage in error throw Error(`Failed to deserialize "${path}" as "${schema}" in "${this.mode}" mode`); } default: // everything else should be binary data // eslint-disable-next-line @typescript-eslint/no-explicit-any return serialized; } }); } } exports.IExecDataProtectorDeserializer = IExecDataProtectorDeserializer; //# sourceMappingURL=index.js.map