UNPKG

s3db.js

Version:

Use AWS S3, the world's most reliable document storage, as a database with this ORM.

98 lines (82 loc) 2.69 kB
import { merge, isString } from "lodash-es"; import FastestValidator from "fastest-validator"; import { encrypt } from "./concerns/crypto.js"; import tryFn, { tryFnSync } from "./concerns/try-fn.js"; import { ValidationError } from "./errors.js"; async function secretHandler (actual, errors, schema) { if (!this.passphrase) { errors.push(new ValidationError("Missing configuration for secrets encryption.", { actual, type: "encryptionKeyMissing", suggestion: "Provide a passphrase for secret encryption." })); return actual; } const [ok, err, res] = await tryFn(() => encrypt(String(actual), this.passphrase)); if (ok) return res; errors.push(new ValidationError("Problem encrypting secret.", { actual, type: "encryptionProblem", error: err, suggestion: "Check the passphrase and input value." })); return actual; } async function jsonHandler (actual, errors, schema) { if (isString(actual)) return actual; const [ok, err, json] = tryFnSync(() => JSON.stringify(actual)); if (!ok) throw new ValidationError("Failed to stringify JSON", { original: err, input: actual }); return json; } export class Validator extends FastestValidator { constructor({ options, passphrase, autoEncrypt = true } = {}) { super(merge({}, { useNewCustomCheckerFunction: true, messages: { encryptionKeyMissing: "Missing configuration for secrets encryption.", encryptionProblem: "Problem encrypting secret. Actual: {actual}. Error: {error}", }, defaults: { string: { trim: true, }, object: { strict: "remove", }, number: { convert: true, } }, }, options)) this.passphrase = passphrase; this.autoEncrypt = autoEncrypt; this.alias('secret', { type: "string", custom: this.autoEncrypt ? secretHandler : undefined, messages: { string: "The '{field}' field must be a string.", stringMin: "This secret '{field}' field length must be at least {expected} long.", }, }) this.alias('secretAny', { type: "any" , custom: this.autoEncrypt ? secretHandler : undefined, }) this.alias('secretNumber', { type: "number", custom: this.autoEncrypt ? secretHandler : undefined, }) this.alias('json', { type: "any", custom: this.autoEncrypt ? jsonHandler : undefined, }) } } export const ValidatorManager = new Proxy(Validator, { instance: null, construct(target, args) { if (!this.instance) this.instance = new target(...args); return this.instance; } }) export default Validator;