mirror of
https://github.com/n8n-io/n8n.git
synced 2026-08-28 17:22:01 +08:00
chore: Align private/dynamic credential wording to "end-user credentials" (#33865)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
993e1c8b72
commit
31e75b9022
@@ -96,7 +96,7 @@ export const scopeInformation: Partial<Record<Scope, ScopeInformation>> = {
|
||||
},
|
||||
'credential:connect': {
|
||||
displayName: 'Connect Credential',
|
||||
description: 'Allows connecting an own account to a private credential.',
|
||||
description: 'Allows connecting an own account to an end-user credential.',
|
||||
},
|
||||
'insights:read': {
|
||||
displayName: 'Read Insights',
|
||||
|
||||
@@ -1074,7 +1074,7 @@ describe('TelemetryEventRelay', () => {
|
||||
|
||||
eventService.emit('private-credential-created', event);
|
||||
|
||||
expect(telemetry.track).toHaveBeenCalledWith('User created private credential', {
|
||||
expect(telemetry.track).toHaveBeenCalledWith('User created end-user credential', {
|
||||
user_id: 'user123',
|
||||
user_role: GLOBAL_OWNER_ROLE.slug,
|
||||
credential_type: 'gmailOAuth2',
|
||||
@@ -1099,7 +1099,7 @@ describe('TelemetryEventRelay', () => {
|
||||
|
||||
eventService.emit('private-credential-toggled-to-private', event);
|
||||
|
||||
expect(telemetry.track).toHaveBeenCalledWith('User made credential private', {
|
||||
expect(telemetry.track).toHaveBeenCalledWith('User made credential end-user', {
|
||||
user_id: 'user123',
|
||||
user_role: GLOBAL_OWNER_ROLE.slug,
|
||||
credential_type: 'gmailOAuth2',
|
||||
@@ -1122,7 +1122,7 @@ describe('TelemetryEventRelay', () => {
|
||||
|
||||
eventService.emit('private-credential-toggled-to-static', event);
|
||||
|
||||
expect(telemetry.track).toHaveBeenCalledWith('User made credential static', {
|
||||
expect(telemetry.track).toHaveBeenCalledWith('User made credential fixed', {
|
||||
user_id: 'user123',
|
||||
user_role: GLOBAL_OWNER_ROLE.slug,
|
||||
credential_type: 'gmailOAuth2',
|
||||
@@ -1145,7 +1145,7 @@ describe('TelemetryEventRelay', () => {
|
||||
|
||||
eventService.emit('private-credential-deleted', event);
|
||||
|
||||
expect(telemetry.track).toHaveBeenCalledWith('User deleted private credential', {
|
||||
expect(telemetry.track).toHaveBeenCalledWith('User deleted end-user credential', {
|
||||
user_id: 'user123',
|
||||
user_role: GLOBAL_OWNER_ROLE.slug,
|
||||
credential_type: 'gmailOAuth2',
|
||||
@@ -1164,7 +1164,7 @@ describe('TelemetryEventRelay', () => {
|
||||
|
||||
eventService.emit('private-credential-user-connected', event);
|
||||
|
||||
expect(telemetry.track).toHaveBeenCalledWith('User connected to private credential', {
|
||||
expect(telemetry.track).toHaveBeenCalledWith('User connected to end-user credential', {
|
||||
user_id: 'user123',
|
||||
user_role: undefined,
|
||||
credential_type: 'gmailOAuth2',
|
||||
@@ -1667,13 +1667,13 @@ describe('TelemetryEventRelay', () => {
|
||||
user_id: 'user123',
|
||||
version_cli: N8N_VERSION,
|
||||
workflow_id: 'workflow123',
|
||||
used_private_credentials: false,
|
||||
private_credentials_attempted_count: 0,
|
||||
private_credentials_resolved_count: 0,
|
||||
used_end_user_credentials: false,
|
||||
end_user_credentials_attempted_count: 0,
|
||||
end_user_credentials_resolved_count: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it('should set `used_private_credentials` when a private credential resolution was attempted but failed', async () => {
|
||||
it('should set `used_end_user_credentials` when an end-user credential resolution was attempted but failed', async () => {
|
||||
const event: RelayEventMap['workflow-post-execute'] = {
|
||||
workflow: mock<IWorkflowDb>({
|
||||
id: 'workflow123',
|
||||
@@ -1701,14 +1701,14 @@ describe('TelemetryEventRelay', () => {
|
||||
|
||||
expect(telemetry.trackWorkflowExecution).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
used_private_credentials: true,
|
||||
private_credentials_attempted_count: 1,
|
||||
private_credentials_resolved_count: 0,
|
||||
used_end_user_credentials: true,
|
||||
end_user_credentials_attempted_count: 1,
|
||||
end_user_credentials_resolved_count: 0,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should count attempted vs resolved private credentials and the effective resolver', async () => {
|
||||
it('should count attempted vs resolved end-user credentials and the effective resolver', async () => {
|
||||
dynamicCredentialsProxy.getEffectiveResolverId.mockReturnValueOnce('system-n8n');
|
||||
|
||||
const event: RelayEventMap['workflow-post-execute'] = {
|
||||
@@ -1738,9 +1738,9 @@ describe('TelemetryEventRelay', () => {
|
||||
|
||||
expect(telemetry.trackWorkflowExecution).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
used_private_credentials: true,
|
||||
private_credentials_attempted_count: 2,
|
||||
private_credentials_resolved_count: 1,
|
||||
used_end_user_credentials: true,
|
||||
end_user_credentials_attempted_count: 2,
|
||||
end_user_credentials_resolved_count: 1,
|
||||
credential_resolver_id: 'system-n8n',
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -721,7 +721,7 @@ export class TelemetryEventRelay extends EventRelay {
|
||||
projectId,
|
||||
projectType,
|
||||
}: RelayEventMap['private-credential-created']) {
|
||||
this.telemetry.track('User created private credential', {
|
||||
this.telemetry.track('User created end-user credential', {
|
||||
user_id: user.id,
|
||||
user_role: user.role?.slug,
|
||||
credential_type: credentialType,
|
||||
@@ -736,7 +736,7 @@ export class TelemetryEventRelay extends EventRelay {
|
||||
credentialId,
|
||||
credentialType,
|
||||
}: RelayEventMap['private-credential-toggled-to-private']) {
|
||||
this.telemetry.track('User made credential private', {
|
||||
this.telemetry.track('User made credential end-user', {
|
||||
user_id: user.id,
|
||||
user_role: user.role?.slug,
|
||||
credential_type: credentialType,
|
||||
@@ -749,7 +749,7 @@ export class TelemetryEventRelay extends EventRelay {
|
||||
credentialId,
|
||||
credentialType,
|
||||
}: RelayEventMap['private-credential-toggled-to-static']) {
|
||||
this.telemetry.track('User made credential static', {
|
||||
this.telemetry.track('User made credential fixed', {
|
||||
user_id: user.id,
|
||||
user_role: user.role?.slug,
|
||||
credential_type: credentialType,
|
||||
@@ -762,7 +762,7 @@ export class TelemetryEventRelay extends EventRelay {
|
||||
credentialId,
|
||||
credentialType,
|
||||
}: RelayEventMap['private-credential-connections-cleared']) {
|
||||
this.telemetry.track('User cleared private credential connections', {
|
||||
this.telemetry.track('User cleared end-user credential connections', {
|
||||
user_id: user.id,
|
||||
user_role: user.role?.slug,
|
||||
credential_type: credentialType,
|
||||
@@ -775,7 +775,7 @@ export class TelemetryEventRelay extends EventRelay {
|
||||
credentialId,
|
||||
credentialType,
|
||||
}: RelayEventMap['private-credential-deleted']) {
|
||||
this.telemetry.track('User deleted private credential', {
|
||||
this.telemetry.track('User deleted end-user credential', {
|
||||
user_id: user.id,
|
||||
user_role: user.role?.slug,
|
||||
credential_type: credentialType,
|
||||
@@ -790,7 +790,7 @@ export class TelemetryEventRelay extends EventRelay {
|
||||
supportsManagedAuth,
|
||||
usesManagedAuth,
|
||||
}: RelayEventMap['private-credential-user-connected']) {
|
||||
this.telemetry.track('User connected to private credential', {
|
||||
this.telemetry.track('User connected to end-user credential', {
|
||||
user_id: user.id,
|
||||
user_role: user.role?.slug,
|
||||
credential_type: credentialType,
|
||||
@@ -1194,9 +1194,9 @@ export class TelemetryEventRelay extends EventRelay {
|
||||
version_cli: N8N_VERSION,
|
||||
success: false,
|
||||
...executionTelemetryProperties,
|
||||
used_private_credentials: privateCredentialsAttemptedCount > 0,
|
||||
private_credentials_attempted_count: privateCredentialsAttemptedCount,
|
||||
private_credentials_resolved_count: privateCredentialsResolvedCount,
|
||||
used_end_user_credentials: privateCredentialsAttemptedCount > 0,
|
||||
end_user_credentials_attempted_count: privateCredentialsAttemptedCount,
|
||||
end_user_credentials_resolved_count: privateCredentialsResolvedCount,
|
||||
};
|
||||
|
||||
if (privateCredentialsAttemptedCount > 0) {
|
||||
@@ -1300,11 +1300,11 @@ export class TelemetryEventRelay extends EventRelay {
|
||||
is_managed: false,
|
||||
eval_rows_left: null,
|
||||
meta: JSON.stringify(workflow.meta),
|
||||
used_private_credentials: telemetryProperties.used_private_credentials,
|
||||
private_credentials_attempted_count:
|
||||
telemetryProperties.private_credentials_attempted_count,
|
||||
private_credentials_resolved_count:
|
||||
telemetryProperties.private_credentials_resolved_count,
|
||||
used_end_user_credentials: telemetryProperties.used_end_user_credentials,
|
||||
end_user_credentials_attempted_count:
|
||||
telemetryProperties.end_user_credentials_attempted_count,
|
||||
end_user_credentials_resolved_count:
|
||||
telemetryProperties.end_user_credentials_resolved_count,
|
||||
credential_resolver_id: telemetryProperties.credential_resolver_id,
|
||||
...executionTelemetryProperties,
|
||||
...TelemetryHelpers.resolveAIMetrics(workflow.nodes, this.nodeTypes),
|
||||
|
||||
@@ -187,11 +187,11 @@ export interface IExecutionTrackProperties extends ITelemetryTrackProperties {
|
||||
error_node_type?: string;
|
||||
is_manual: boolean;
|
||||
crashed?: boolean;
|
||||
used_private_credentials?: boolean;
|
||||
/** Number of nodes that attempted to resolve a private credential (regardless of success). */
|
||||
private_credentials_attempted_count?: number;
|
||||
/** Number of nodes that successfully resolved a private credential. */
|
||||
private_credentials_resolved_count?: number;
|
||||
used_end_user_credentials?: boolean;
|
||||
/** Number of nodes that attempted to resolve an end-user credential (regardless of success). */
|
||||
end_user_credentials_attempted_count?: number;
|
||||
/** Number of nodes that successfully resolved an end-user credential. */
|
||||
end_user_credentials_resolved_count?: number;
|
||||
/** Effective resolver id the execution ran with (workflow override or seeded system resolver). */
|
||||
credential_resolver_id?: string;
|
||||
execution_source?: WorkflowExecutionSource;
|
||||
|
||||
@@ -455,7 +455,7 @@ export class LoadNodesAndCredentials {
|
||||
|
||||
// Create the main context establishment hooks property as a fixedCollection
|
||||
const contextHooksProperty: INodeProperties = {
|
||||
displayName: 'Identify user for dynamic credentials',
|
||||
displayName: 'Identify user for end-user credentials',
|
||||
name: 'contextEstablishmentHooks',
|
||||
type: 'fixedCollection',
|
||||
placeholder: 'Add User Identifier',
|
||||
|
||||
@@ -382,8 +382,8 @@ export class Telemetry {
|
||||
this.addExecutionTrackData(workflowId, sourceKey, execTime);
|
||||
}
|
||||
|
||||
if (properties.used_private_credentials) {
|
||||
this.track('Workflow execution with private credentials', properties);
|
||||
if (properties.used_end_user_credentials) {
|
||||
this.track('Workflow execution with end-user credentials', properties);
|
||||
}
|
||||
|
||||
if (
|
||||
|
||||
@@ -742,7 +742,7 @@ describe('WorkflowValidationService', () => {
|
||||
const result = await service.validateDynamicCredentials(nodes, mockNodeTypes);
|
||||
|
||||
expect(result.isValid).toBe(false);
|
||||
expect(result.error).toContain('dynamic credentials');
|
||||
expect(result.error).toContain('end-user credentials');
|
||||
expect(result.error).toContain('"My OAuth2"');
|
||||
expect(result.error).toContain('resolver');
|
||||
});
|
||||
@@ -816,7 +816,7 @@ describe('WorkflowValidationService', () => {
|
||||
const result = await service.validateDynamicCredentials(nodes, mockNodeTypes);
|
||||
|
||||
expect(result.isValid).toBe(false);
|
||||
expect(result.error).toContain('dynamic credentials');
|
||||
expect(result.error).toContain('end-user credentials');
|
||||
expect(result.error).toContain('"My OAuth2"');
|
||||
expect(result.error).toContain('identity extractor');
|
||||
});
|
||||
@@ -842,7 +842,7 @@ describe('WorkflowValidationService', () => {
|
||||
const result = await service.validateDynamicCredentials(nodes, mockNodeTypes);
|
||||
|
||||
expect(result.isValid).toBe(false);
|
||||
expect(result.error).toContain('dynamic credentials');
|
||||
expect(result.error).toContain('end-user credentials');
|
||||
expect(result.error).toContain('identity extractor');
|
||||
});
|
||||
|
||||
|
||||
@@ -346,7 +346,7 @@ export class WorkflowValidationService {
|
||||
triggers: { hasExternalIdentityTrigger: boolean; hasN8nIdentityTrigger: boolean },
|
||||
): string | undefined {
|
||||
if (!workflowResolverId) {
|
||||
return `dynamic credentials (${credNames}) require a resolver to be configured.`;
|
||||
return `end-user credentials (${credNames}) require a resolver to be configured.`;
|
||||
}
|
||||
|
||||
const { hasExternalIdentityTrigger, hasN8nIdentityTrigger } = triggers;
|
||||
@@ -361,7 +361,7 @@ export class WorkflowValidationService {
|
||||
// Custom resolver: needs an external identity from the trigger.
|
||||
return hasExternalIdentityTrigger
|
||||
? undefined
|
||||
: `dynamic credentials (${credNames}) require a trigger with an identity extractor configured. Please configure an identity extractor on the trigger node.`;
|
||||
: `end-user credentials (${credNames}) require a trigger with an identity extractor configured. Please configure an identity extractor on the trigger node.`;
|
||||
}
|
||||
|
||||
/** Collects the ids of all credentials referenced by enabled nodes. */
|
||||
|
||||
@@ -124,7 +124,7 @@ describe('ResolversView', () => {
|
||||
const { getByText } = renderComponent({ pinia });
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByText('Resolve private credentials from user identity')).toBeInTheDocument();
|
||||
expect(getByText('Resolve end-user credentials from user identity')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -135,7 +135,7 @@ describe('ResolversView', () => {
|
||||
|
||||
// Wait for empty state to be displayed (after loading completes)
|
||||
await waitFor(() => {
|
||||
expect(getByText('Resolve private credentials from user identity')).toBeInTheDocument();
|
||||
expect(getByText('Resolve end-user credentials from user identity')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Now the Add Resolver button should be available
|
||||
|
||||
@@ -117,7 +117,7 @@ async function onAction(action: string, resolver: CredentialResolver) {
|
||||
<div :class="$style.iconCard"><N8nIcon icon="user" /></div>
|
||||
</div>
|
||||
<N8nHeading tag="h2" size="medium" align="center" class="mb-2xs">
|
||||
Resolve private credentials from user identity
|
||||
Resolve end-user credentials from user identity
|
||||
</N8nHeading>
|
||||
<div>
|
||||
{{ i18n.baseText('credentialResolver.view.description') }}
|
||||
|
||||
@@ -14,7 +14,7 @@ export class DynamicCredentialCheck implements INodeType {
|
||||
group: ['transform'],
|
||||
version: 1,
|
||||
description:
|
||||
'Checks whether the triggering user has the required Private credential configured. Routes to "Ready" or "Not Ready" and returns auth URLs when the credential is missing.',
|
||||
'Checks whether the triggering user has the required end-user credential configured. Routes to "Ready" or "Not Ready" and returns auth URLs when the credential is missing.',
|
||||
defaults: {
|
||||
name: 'Check Credential Status',
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user