fix(core): Do not save credential overwrites data into the database (#13170)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2025-02-10 17:24:36 +01:00
committed by GitHub
parent dd6d30c3d4
commit 298a7b0038
7 changed files with 153 additions and 62 deletions

View File

@@ -118,4 +118,74 @@ describe('Credentials', () => {
},
);
});
describe('updateData', () => {
const nodeCredentials = { id: '123', name: 'Test Credential' };
const credentialType = 'testApi';
test('should update existing data', () => {
const credentials = new Credentials(
nodeCredentials,
credentialType,
cipher.encrypt({
username: 'olduser',
password: 'oldpass',
apiKey: 'oldkey',
}),
);
credentials.updateData({ username: 'newuser', password: 'newpass' });
expect(credentials.getData()).toEqual({
username: 'newuser',
password: 'newpass',
apiKey: 'oldkey',
});
});
test('should delete specified keys', () => {
const credentials = new Credentials(
nodeCredentials,
credentialType,
cipher.encrypt({
username: 'testuser',
password: 'testpass',
apiKey: 'testkey',
}),
);
credentials.updateData({}, ['username', 'apiKey']);
expect(credentials.getData()).toEqual({
password: 'testpass',
});
});
test('should update and delete keys in same operation', () => {
const credentials = new Credentials(
nodeCredentials,
credentialType,
cipher.encrypt({
username: 'olduser',
password: 'oldpass',
apiKey: 'oldkey',
}),
);
credentials.updateData({ username: 'newuser' }, ['apiKey']);
expect(credentials.getData()).toEqual({
username: 'newuser',
password: 'oldpass',
});
});
test('should throw an error if no data was previously set', () => {
const credentials = new Credentials(nodeCredentials, credentialType);
expect(() => {
credentials.updateData({ username: 'newuser' });
}).toThrow(CREDENTIAL_ERRORS.NO_DATA);
});
});
});

View File

@@ -30,6 +30,18 @@ export class Credentials<
this.data = this.cipher.encrypt(data);
}
/**
* Update parts of the credential data.
* This decrypts the data, modifies it, and then re-encrypts the updated data back to a string.
*/
updateData(toUpdate: Partial<T>, toDelete: Array<keyof T> = []) {
const updatedData: T = { ...this.getData(), ...toUpdate };
for (const key of toDelete) {
delete updatedData[key];
}
this.setData(updatedData);
}
/**
* Returns the decrypted credential object
*/