fix(core): Guard against undefined config properties in credential overwrites (#28573)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jon 2026-04-17 17:42:34 +01:00 committed by GitHub
parent 25e07cab5a
commit 77d27bc826
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 40 additions and 4 deletions

View file

@ -113,6 +113,36 @@ describe('CredentialsOverwrites', () => {
expect(result).toEqual(data);
});
it('should not crash when skipTypes is undefined', () => {
// Simulate version mismatch where skipTypes is not present on the config object
globalConfig.credentials.overwrite.skipTypes =
undefined as unknown as CommaSeparatedStringArray<string>;
const result = credentialsOverwrites.applyOverwrite('test', {
username: '',
password: '',
});
expect(result).toEqual({ username: 'user', password: 'pass' });
});
it('should not crash when overwrite config object is undefined', () => {
// Simulate a DI/version mismatch where the nested overwrite config is undefined
const savedOverwrite = globalConfig.credentials.overwrite;
globalConfig.credentials.overwrite = undefined as never;
try {
const result = credentialsOverwrites.applyOverwrite('test', {
username: '',
password: '',
});
expect(result).toEqual({ username: 'user', password: 'pass' });
} finally {
globalConfig.credentials.overwrite = savedOverwrite;
}
});
describe('N8N_SKIP_CREDENTIAL_OVERWRITE', () => {
beforeEach(() => {
globalConfig.credentials.overwrite.skipTypes = [

View file

@ -147,7 +147,7 @@ export class CredentialsOverwrites {
// customized (any overwrite field has a non-empty value that differs from
// the overwrite value). Since overwrites are never persisted to the DB,
// any non-empty stored value that differs from the overwrite is user-set.
if (this.globalConfig.credentials.overwrite.skipTypes.includes(type)) {
if (this.globalConfig.credentials.overwrite?.skipTypes?.includes(type)) {
const isFieldCustomized = (key: string) => {
const storedValue = data[key];
return (
@ -208,11 +208,17 @@ export class CredentialsOverwrites {
private get(name: string): ICredentialDataDecryptedObject | undefined {
const parentTypes = this.credentialTypes.getParentTypes(name);
return [name, ...parentTypes]
const entries = [name, ...parentTypes]
.reverse()
.map((type) => this.overwriteData[type])
.filter((type) => !!type)
.reduce((acc, current) => Object.assign(acc, current), {});
.filter((type): type is ICredentialDataDecryptedObject => !!type);
if (entries.length === 0) return undefined;
return entries.reduce(
(acc, current) => Object.assign(acc, current),
{} as ICredentialDataDecryptedObject,
);
}
getAll(): ICredentialsOverwrite {