feat(core): Add system resolver id lookup to DynamicCredentialsProxy (#30790)

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Guillaume Jacquart 2026-05-20 16:24:15 +02:00 committed by GitHub
parent 6edb238a7c
commit d7d8519515
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 47 additions and 0 deletions

View File

@ -813,6 +813,7 @@ describe('CredentialsHelper', () => {
describe('getDecrypted - credential resolution integration', () => {
const mockCredentialResolutionProvider = {
resolveIfNeeded: jest.fn(),
getSystemResolverId: jest.fn(),
};
const mockAdditionalData = {

View File

@ -33,6 +33,7 @@ describe('DynamicCredentialsProxy', () => {
mockResolverProvider = {
resolveIfNeeded: jest.fn(),
getSystemResolverId: jest.fn(),
};
mockStorageProvider = {
@ -207,4 +208,18 @@ describe('DynamicCredentialsProxy', () => {
expect(() => proxy.setStorageProvider(mockStorageProvider)).not.toThrow();
});
});
describe('getSystemResolverId', () => {
it('returns null when no resolver provider is set', () => {
expect(proxy.getSystemResolverId()).toBeNull();
});
it('delegates to the resolver provider when set', () => {
mockResolverProvider.getSystemResolverId.mockReturnValue('system-n8n');
proxy.setResolverProvider(mockResolverProvider);
expect(proxy.getSystemResolverId()).toBe('system-n8n');
expect(mockResolverProvider.getSystemResolverId).toHaveBeenCalled();
});
});
});

View File

@ -39,4 +39,11 @@ export interface ICredentialResolutionProvider {
executionContext?: IExecutionContext,
workflowSettings?: IWorkflowSettings,
): Promise<CredentialResolutionResult>;
/**
* Returns the seeded system resolver id used to store private credentials
* on the running user's behalf (e.g. OAuth2 callback for `isResolvable`
* credentials). Returns null when the provider is unavailable.
*/
getSystemResolverId(): string | null;
}

View File

@ -37,6 +37,19 @@ export class DynamicCredentialsProxy
this.resolvingProvider = provider;
}
/**
* Returns the seeded system resolver id used to store private credentials
* on the user's behalf (e.g. OAuth2 callback for `isResolvable` credentials).
* Returns null when the system resolver has not been seeded or the dynamic
* credentials provider is not registered.
*/
getSystemResolverId(): string | null {
if (!this.resolvingProvider) {
return null;
}
return this.resolvingProvider.getSystemResolverId();
}
async resolveIfNeeded(
credentialsResolveMetadata: CredentialResolveMetadata,
staticData: ICredentialDataDecryptedObject,

View File

@ -1092,4 +1092,10 @@ describe('DynamicCredentialService', () => {
});
});
});
describe('getSystemResolverId', () => {
it('returns the seeded system resolver id constant', () => {
expect(service.getSystemResolverId()).toBe('system-n8n');
});
});
});

View File

@ -21,6 +21,7 @@ import type {
CredentialResolveMetadata,
ICredentialResolutionProvider,
} from '../../../credentials/credential-resolution-provider.interface';
import { SYSTEM_RESOLVER_ID } from '../constants';
import { DynamicCredentialResolverRepository } from '../database/repositories/credential-resolver.repository';
import { DynamicCredentialsConfig } from '../dynamic-credentials.config';
import { CredentialResolutionError } from '../errors/credential-resolution.error';
@ -143,6 +144,10 @@ export class DynamicCredentialService implements ICredentialResolutionProvider {
}
}
getSystemResolverId(): string {
return SYSTEM_RESOLVER_ID;
}
/**
* Builds credential context from execution context by decrypting the credentials field
*/