UNPKG

@saleor/app-sdk

Version:
147 lines (139 loc) 5.99 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/settings-manager/encrypted-metadata-manager.ts var _crypto = require('crypto'); var _crypto2 = _interopRequireDefault(_crypto); // src/settings-manager/metadata-manager.ts var deserializeMetadata = ({ key, value }) => { const [newKey, domain] = key.split("__"); return { key: newKey, domain, value }; }; var constructDomainSpecificKey = (key, saleorApiUrl) => [key, saleorApiUrl].join("__"); var serializeSettingsToMetadata = ({ key, value, domain }) => { if (!domain) { return { key, value }; } return { key: constructDomainSpecificKey(key, domain), value }; }; var MetadataManager = class { constructor({ fetchMetadata, mutateMetadata, deleteMetadata }) { this.settings = []; this.fetchMetadata = fetchMetadata; this.mutateMetadata = mutateMetadata; this.deleteMetadata = deleteMetadata; } async get(key, domain) { if (!this.settings.length) { const metadata = await this.fetchMetadata(); this.settings = metadata.map(deserializeMetadata); } const setting = this.settings.find((md) => md.key === key && md.domain === domain); return _optionalChain([setting, 'optionalAccess', _ => _.value]); } async set(settings) { let serializedMetadata = []; if (Array.isArray(settings)) { serializedMetadata = settings.map(serializeSettingsToMetadata); } else { serializedMetadata = [serializeSettingsToMetadata(settings)]; } const metadata = await this.mutateMetadata(serializedMetadata); this.settings = metadata.map(deserializeMetadata); } /** * Typescript doesn't properly infer arguments, so they have to be rewritten explicitly */ async delete(args) { if (!this.deleteMetadata) { throw new Error( "Delete not implemented. Ensure MetadataManager is configured with deleteMetadata param in constructor" ); } const argsArray = Array.isArray(args) ? args : [args]; const keysToDelete = argsArray.map((keyOrDomainPair) => { if (typeof keyOrDomainPair === "string") { return keyOrDomainPair; } const { key, domain } = keyOrDomainPair; return constructDomainSpecificKey(key, domain); }); await this.deleteMetadata(keysToDelete); this.settings = this.settings.filter((setting) => !argsArray.includes(setting.key)); } }; // src/settings-manager/encrypted-metadata-manager.ts var prepareKey = (key) => _crypto2.default.createHash("sha256").update(String(key)).digest("base64").substr(0, 32); var encrypt = (data, key) => { const iv = _crypto2.default.randomBytes(16).toString("hex").slice(0, 16); const cipher = _crypto2.default.createCipheriv("aes256", prepareKey(key), iv); let encrypted = cipher.update(data, "utf8", "hex"); encrypted += cipher.final("hex"); return `${iv}${encrypted}`; }; var decrypt = (data, key) => { const [iv, encrypted] = [data.slice(0, 16), data.slice(16)]; const decipher = _crypto2.default.createDecipheriv("aes256", prepareKey(key), iv); let message = decipher.update(encrypted, "hex", "utf8"); message += decipher.final("utf8"); return message; }; var EncryptedMetadataManager = class { constructor({ fetchMetadata, mutateMetadata, encryptionKey, encryptionMethod, decryptionMethod, deleteMetadata }) { this.metadataManager = new MetadataManager({ fetchMetadata, mutateMetadata, deleteMetadata }); if (encryptionKey) { this.encryptionKey = encryptionKey; } else { console.warn("Encrypted Metadata Manager secret key has not been set."); if (process.env.NODE_ENV === "production") { console.error("Can't start the application without the secret key."); throw new Error( "Encryption key for the EncryptedMetadataManager has not been set. Setting it for the production environments is necessary. You can find more in the documentation: https://docs.saleor.io/docs/3.x/developer/extending/apps/developing-apps/app-sdk/settings-manager" ); } console.warn( "WARNING: Encrypted Metadata Manager encryption key has not been set. For production deployments, it need's to be set" ); console.warn("Using placeholder value for the development."); this.encryptionKey = "CHANGE_ME"; } this.encryptionMethod = encryptionMethod || encrypt; this.decryptionMethod = decryptionMethod || decrypt; } async get(key, domain) { const encryptedValue = await this.metadataManager.get(key, domain); if (!encryptedValue) { return void 0; } return this.decryptionMethod(encryptedValue, this.encryptionKey); } async set(settings) { if (!Array.isArray(settings)) { const encryptedValue = this.encryptionMethod(settings.value, this.encryptionKey); return this.metadataManager.set({ ...settings, value: encryptedValue }); } const encryptedSettings = settings.map((s) => ({ ...s, value: this.encryptionMethod(s.value, this.encryptionKey) })); return this.metadataManager.set(encryptedSettings); } async delete(args) { await this.metadataManager.delete(args); } }; exports.EncryptedMetadataManager = EncryptedMetadataManager; exports.MetadataManager = MetadataManager; exports.decrypt = decrypt; exports.encrypt = encrypt;