Files
outline/server/models/decorators/Encrypted.ts

55 lines
1.5 KiB
TypeScript

import isNil from "lodash/isNil";
import vaults from "@server/database/vaults";
import Logger from "@server/logging/Logger";
const key = "sequelize:vault";
/**
* A decorator that stores the encrypted vault for a particular database column
* so that it can be used by getters and setters. Must be accompanied by a
* @Column(DataType.BLOB) annotation.
*/
export default function Encrypted(target: any, propertyKey: string) {
Reflect.defineMetadata(key, vaults().vault(propertyKey), target, propertyKey);
}
/**
* Get the value of an encrypted column given the target and the property key.
*/
export function getEncryptedColumn(target: any, propertyKey: string): string {
if (!target.getDataValue(propertyKey)) {
return "";
}
try {
return Reflect.getMetadata(key, target, propertyKey).get.call(target);
} catch (err) {
if (err.message.includes("Unexpected end of JSON input")) {
return "";
}
if (err.message.includes("bad decrypt")) {
Logger.error(
`Failed to decrypt database column (${propertyKey}). The SECRET_KEY environment variable may have changed since installation.`,
err
);
process.exit(1);
}
throw err;
}
}
/**
* Set the value of an encrypted column given the target and the property key.
*/
export function setEncryptedColumn(
target: any,
propertyKey: string,
value: string
) {
if (isNil(value)) {
target.setDataValue(propertyKey, value);
} else {
Reflect.getMetadata(key, target, propertyKey).set.call(target, value);
}
}