n8n/packages/core/src/credentials.ts
कारतोफ्फेलस्क्रिप्ट™ 0c86bf2b37
fix(core): Improve error handling in credential decryption and parsing (#12868)
2025-01-27 20:03:34 +01:00

66 lines
1.6 KiB
TypeScript

import { Container } from '@n8n/di';
import type { ICredentialDataDecryptedObject, ICredentialsEncrypted } from 'n8n-workflow';
import { ApplicationError, ICredentials, jsonParse } from 'n8n-workflow';
import { CREDENTIAL_ERRORS } from '@/constants';
import { Cipher } from '@/encryption/cipher';
class CredentialDataError extends ApplicationError {
constructor({ name, type, id }: Credentials<object>, message: string, cause?: unknown) {
super(message, {
extra: { name, type, id },
cause,
});
}
}
export class Credentials<
T extends object = ICredentialDataDecryptedObject,
> extends ICredentials<T> {
private readonly cipher = Container.get(Cipher);
/**
* Sets new credential object
*/
setData(data: T): void {
this.data = this.cipher.encrypt(data);
}
/**
* Returns the decrypted credential object
*/
getData(): T {
if (this.data === undefined) {
throw new CredentialDataError(this, CREDENTIAL_ERRORS.NO_DATA);
}
let decryptedData: string;
try {
decryptedData = this.cipher.decrypt(this.data);
} catch (cause) {
throw new CredentialDataError(this, CREDENTIAL_ERRORS.DECRYPTION_FAILED, cause);
}
try {
return jsonParse(decryptedData);
} catch (cause) {
throw new CredentialDataError(this, CREDENTIAL_ERRORS.INVALID_JSON, cause);
}
}
/**
* Returns the encrypted credentials to be saved
*/
getDataToSave(): ICredentialsEncrypted {
if (this.data === undefined) {
throw new ApplicationError('No credentials were set to save.');
}
return {
id: this.id,
name: this.name,
type: this.type,
data: this.data,
};
}
}