master-zapier-plan-draft/vendor/zapier-platform/packages/schema/lib/functional-constraints/AuthFieldisSafe.js
George Lambert b4150c8250 Milestone 0: import zappier billing, Verae middleware, and Zapier research
Compose-ready workspace: packages/zappier (rate card, portal, Stripe),
packages/verae-zapier-middleware (timestamp + NATS), packages/verae-zapier
(CLI app), vendor/zapier-platform, and research/zapier vendor corpus.

Gate 0 structure checks pass. Product code and research are not yet wired.
2026-09-09 02:37:36 -04:00

85 lines
2.1 KiB
JavaScript

'use strict';
const jsonschema = require('jsonschema');
const AUTH_FIELD_ID = '/AuthFieldSchema';
const AUTH_FIELDS_ID = '/AuthFieldsSchema';
const FORBIDDEN_KEYS = [
'access_token',
'access-token',
'accesstoken',
'api_key',
'apikey',
'api-key',
'auth',
'jwt',
'passwd',
'password',
'pswd',
'refresh_token',
'refresh-token',
'refreshtoken',
'secret',
'set-cookie',
'set_cookie',
'setcookie',
'signature',
'token',
];
const isSensitiveKey = (key = '') =>
FORBIDDEN_KEYS.some((forbidden) => key.toLowerCase().includes(forbidden));
const checkAuthField = (field) => {
const errors = [];
// if the field key contains any forbidden substring (case-insensitive),
// AND 'isNoSecret' is true, throw a validation error
if (
(field.key === 'password' || isSensitiveKey(field.key)) &&
field.isNoSecret === true
) {
errors.push(
new jsonschema.ValidationError(
`cannot set isNoSecret as true for the sensitive key "${field.key}".`,
field,
'/AuthFieldSchema',
'instance.field',
'sensitive',
'field',
),
);
}
return errors;
};
module.exports = (definition, mainSchema) => {
const errors = [];
// Done to validate anti-examples declaratively defined in the schema
if ([AUTH_FIELD_ID, AUTH_FIELDS_ID].includes(mainSchema.id)) {
const definitions = Array.isArray(definition) ? definition : [definition];
definitions.forEach((field, index) => {
checkAuthField(field).forEach((err) => {
err.property = `instance[${index}]`;
err.stack = err.stack.replace('instance.field', err.property);
errors.push(err);
});
});
}
// If there's no authentication or no fields, we have nothing to check
if (!definition.authentication || !definition.authentication.fields) {
return errors;
}
definition.authentication.fields.forEach((field, index) => {
checkAuthField(field).forEach((err) => {
err.property = `instance.authentication.fields[${index}]`;
err.stack = err.stack.replace('instance.field', err.property);
errors.push(err);
});
});
return errors;
};