Skip to content

Commit

Permalink
refactor(core): Allow typings on getCredentials (no-changelog)
Browse files Browse the repository at this point in the history
  • Loading branch information
netroy committed Aug 27, 2024
1 parent 4e15007 commit 3018fd2
Show file tree
Hide file tree
Showing 9 changed files with 34 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export async function validateAuth(context: IWebhookFunctions) {
// Basic authorization is needed to call webhook
let expectedAuth: ICredentialDataDecryptedObject | undefined;
try {
expectedAuth = await context.getCredentials('httpBasicAuth');
expectedAuth = await context.getCredentials<ICredentialDataDecryptedObject>('httpBasicAuth');
} catch {}

if (expectedAuth === undefined || !expectedAuth.user || !expectedAuth.password) {
Expand Down
8 changes: 5 additions & 3 deletions packages/core/src/Credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@ import type { ICredentialDataDecryptedObject, ICredentialsEncrypted } from 'n8n-
import { ApplicationError, ICredentials, jsonParse } from 'n8n-workflow';
import { Cipher } from './Cipher';

export class Credentials extends ICredentials {
export class Credentials<
T extends object = ICredentialDataDecryptedObject,
> extends ICredentials<T> {
private readonly cipher = Container.get(Cipher);

/**
* Sets new credential object
*/
setData(data: ICredentialDataDecryptedObject): void {
setData(data: T): void {
this.data = this.cipher.encrypt(data);
}

/**
* Returns the decrypted credential object
*/
getData(): ICredentialDataDecryptedObject {
getData(): T {
if (this.data === undefined) {
throw new ApplicationError('No data is set so nothing can be returned.');
}
Expand Down
14 changes: 9 additions & 5 deletions packages/core/src/NodeExecuteFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1656,7 +1656,8 @@ export async function httpRequestWithAuthentication(
if (additionalCredentialOptions?.credentialsDecrypted) {
credentialsDecrypted = additionalCredentialOptions.credentialsDecrypted.data;
} else {
credentialsDecrypted = await this.getCredentials(credentialsType);
credentialsDecrypted =
await this.getCredentials<ICredentialDataDecryptedObject>(credentialsType);
}

if (credentialsDecrypted === undefined) {
Expand Down Expand Up @@ -1853,7 +1854,10 @@ export async function requestWithAuthentication(
if (additionalCredentialOptions?.credentialsDecrypted) {
credentialsDecrypted = additionalCredentialOptions.credentialsDecrypted.data;
} else {
credentialsDecrypted = await this.getCredentials(credentialsType, itemIndex);
credentialsDecrypted = await this.getCredentials<ICredentialDataDecryptedObject>(
credentialsType,
itemIndex,
);
}

if (credentialsDecrypted === undefined) {
Expand Down Expand Up @@ -1988,7 +1992,7 @@ export function getAdditionalKeys(
* @param {INode} node Node which request the data
* @param {string} type The credential type to return
*/
export async function getCredentials(
export async function getCredentials<T extends object = ICredentialDataDecryptedObject>(
workflow: Workflow,
node: INode,
type: string,
Expand All @@ -1999,7 +2003,7 @@ export async function getCredentials(
runIndex?: number,
connectionInputData?: INodeExecutionData[],
itemIndex?: number,
): Promise<ICredentialDataDecryptedObject> {
): Promise<T> {
// Get the NodeType as it has the information if the credentials are required
const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
if (nodeType === undefined) {
Expand Down Expand Up @@ -2117,7 +2121,7 @@ export async function getCredentials(
expressionResolveValues,
);

return decryptedDataObject;
return decryptedDataObject as T;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions packages/nodes-base/nodes/Ftp/Ftp.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,9 +510,9 @@ export class Ftp implements INodeType {
const protocol = this.getNodeParameter('protocol', 0) as string;

if (protocol === 'sftp') {
credentials = await this.getCredentials('sftp');
credentials = await this.getCredentials<ICredentialDataDecryptedObject>('sftp');
} else {
credentials = await this.getCredentials('ftp');
credentials = await this.getCredentials<ICredentialDataDecryptedObject>('ftp');
}
let ftp: ftpClient;
let sftp: sftpClient;
Expand Down
2 changes: 1 addition & 1 deletion packages/nodes-base/nodes/Jira/JiraTrigger.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ export class JiraTrigger implements INodeType {
let httpQueryAuth: ICredentialDataDecryptedObject | undefined;

try {
httpQueryAuth = await this.getCredentials('httpQueryAuth');
httpQueryAuth = await this.getCredentials<ICredentialDataDecryptedObject>('httpQueryAuth');
} catch (error) {}

if (httpQueryAuth === undefined || !httpQueryAuth.name || !httpQueryAuth.value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ export class PipedriveTrigger implements INodeType {
let httpBasicAuth: ICredentialDataDecryptedObject | undefined;

try {
httpBasicAuth = await this.getCredentials('httpBasicAuth');
httpBasicAuth = await this.getCredentials<ICredentialDataDecryptedObject>('httpBasicAuth');
} catch (error) {
// Do nothing
}
Expand Down
4 changes: 2 additions & 2 deletions packages/nodes-base/nodes/Webhook/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ export async function validateWebhookAuthentication(
// Basic authorization is needed to call webhook
let expectedAuth: ICredentialDataDecryptedObject | undefined;
try {
expectedAuth = await ctx.getCredentials('httpBasicAuth');
expectedAuth = await ctx.getCredentials<ICredentialDataDecryptedObject>('httpBasicAuth');
} catch {}

if (expectedAuth === undefined || !expectedAuth.user || !expectedAuth.password) {
Expand All @@ -211,7 +211,7 @@ export async function validateWebhookAuthentication(
// Special header with value is needed to call webhook
let expectedAuth: ICredentialDataDecryptedObject | undefined;
try {
expectedAuth = await ctx.getCredentials('httpHeaderAuth');
expectedAuth = await ctx.getCredentials<ICredentialDataDecryptedObject>('httpHeaderAuth');
} catch {}

if (expectedAuth === undefined || !expectedAuth.name || !expectedAuth.value) {
Expand Down
17 changes: 10 additions & 7 deletions packages/workflow/src/Interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export interface IGetCredentials {
get(type: string, id: string | null): Promise<ICredentialsEncrypted>;
}

export abstract class ICredentials {
export abstract class ICredentials<T extends object = ICredentialDataDecryptedObject> {
id?: string;

name: string;
Expand All @@ -106,11 +106,11 @@ export abstract class ICredentials {
this.data = data;
}

abstract getData(nodeType?: string): ICredentialDataDecryptedObject;
abstract getData(nodeType?: string): T;

abstract getDataToSave(): ICredentialsEncrypted;

abstract setData(data: ICredentialDataDecryptedObject): void;
abstract setData(data: T): void;
}

export interface IUser {
Expand All @@ -128,11 +128,11 @@ export type ProjectSharingData = {
updatedAt: string;
};

export interface ICredentialsDecrypted {
export interface ICredentialsDecrypted<T extends object = ICredentialDataDecryptedObject> {
id: string;
name: string;
type: string;
data?: ICredentialDataDecryptedObject;
data?: T;
homeProject?: ProjectSharingData;
sharedWithProjects?: ProjectSharingData[];
}
Expand Down Expand Up @@ -718,7 +718,7 @@ export interface IExecuteWorkflowInfo {

export type ICredentialTestFunction = (
this: ICredentialTestFunctions,
credential: ICredentialsDecrypted,
credential: ICredentialsDecrypted<ICredentialDataDecryptedObject>,
) => Promise<INodeCredentialTestResult>;

export interface ICredentialTestFunctions {
Expand Down Expand Up @@ -860,7 +860,10 @@ export type NodeTypeAndVersion = {

export interface FunctionsBase {
logger: Logger;
getCredentials(type: string, itemIndex?: number): Promise<ICredentialDataDecryptedObject>;
getCredentials<T extends object = ICredentialDataDecryptedObject>(
type: string,
itemIndex?: number,
): Promise<T>;
getCredentialsProperties(type: string): INodeProperties[];
getExecutionId(): string;
getNode(): INode;
Expand Down
4 changes: 3 additions & 1 deletion packages/workflow/src/RoutingNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ export class RoutingNode {
credentials = credentialsDecrypted.data;
} else if (credentialType) {
try {
credentials = (await executeFunctions.getCredentials(credentialType)) || {};
credentials =
(await executeFunctions.getCredentials<ICredentialDataDecryptedObject>(credentialType)) ||
{};
} catch (error) {
if (
nodeType.description.credentials?.length &&
Expand Down

0 comments on commit 3018fd2

Please sign in to comment.