@saleor/app-sdk
Version:
SDK for building great Saleor Apps
147 lines (139 loc) • 5.99 kB
JavaScript
;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;