mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-17 05:29:44 +02:00
fix(core): Expose 1Password fields for secret preview and autocomplete (#40538)
This commit is contained in:
parent
c194d22b5c
commit
bef5f3f97a
|
|
@ -219,7 +219,12 @@ describe('OnePasswordProvider', () => {
|
|||
});
|
||||
expect(provider.getSecret('API Key')).toEqual({ key: 'sk-abc123' });
|
||||
expect(provider.getSecret('SSH Key')).toEqual({ private_key: 'ssh-rsa AAAA...' });
|
||||
expect(provider.getSecretNames()).toHaveLength(3);
|
||||
expect(provider.getSecretNames()).toEqual([
|
||||
'Database Credentials.username',
|
||||
'Database Credentials.password',
|
||||
'API Key.key',
|
||||
'SSH Key.private_key',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should skip items without fields', async () => {
|
||||
|
|
@ -342,5 +347,9 @@ describe('OnePasswordProvider', () => {
|
|||
it('should return false for non-existent secrets', () => {
|
||||
expect(provider.hasSecret('non-existent')).toBe(false);
|
||||
});
|
||||
|
||||
it('should return no field names before secrets are loaded', () => {
|
||||
expect(provider.getSecretNames()).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -193,8 +193,10 @@ export class OnePasswordProvider extends SecretsProvider {
|
|||
return name in this.cachedSecrets;
|
||||
}
|
||||
|
||||
getSecretNames() {
|
||||
return Object.keys(this.cachedSecrets);
|
||||
getSecretNames(): string[] {
|
||||
return Object.entries(this.cachedSecrets).flatMap(([itemName, fields]) =>
|
||||
Object.keys(fields).map((fieldName) => `${itemName}.${fieldName}`),
|
||||
);
|
||||
}
|
||||
|
||||
private async verifyConnection(): Promise<void> {
|
||||
|
|
|
|||
|
|
@ -232,6 +232,26 @@ describe('externalSecretsStore', () => {
|
|||
});
|
||||
|
||||
describe('secretsAsObject', () => {
|
||||
it.each(['secrets', 'projectSecrets'] as const)(
|
||||
'should expose masked 1Password fields from %s for preview and autocomplete',
|
||||
(scope) => {
|
||||
setModuleSettings({ forProjects: true });
|
||||
const store = useExternalSecretsStore();
|
||||
store.state[scope] = {
|
||||
onePassword: ['testing.credential', 'testing.username'],
|
||||
};
|
||||
|
||||
expect(store.secretsAsObject).toEqual({
|
||||
onePassword: {
|
||||
testing: {
|
||||
credential: '*********',
|
||||
username: '*********',
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
it('should only contain the global secrets if forProjects is disabled', () => {
|
||||
setLegacyMode();
|
||||
const store = useExternalSecretsStore();
|
||||
|
|
|
|||
|
|
@ -54,18 +54,19 @@ describe('TelemetryRecorder', () => {
|
|||
|
||||
test('redacts secrets from failure evidence', () => {
|
||||
vi.stubEnv('CONTAINER_TELEMETRY_VERBOSE', '1');
|
||||
vi.stubEnv('GITHUB_HEAD_REF', 'fix-1password-preview');
|
||||
const log = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
const telemetry = new TelemetryRecorder({});
|
||||
|
||||
telemetry.startStage('service:proxy');
|
||||
telemetry.finishStage(
|
||||
'failure',
|
||||
new Error('https://user:password@example.test?token=secret-value'),
|
||||
new Error('https://user:test-password-value@example.test?token=secret-value'),
|
||||
);
|
||||
telemetry.flush(false, 'Authorization: Bearer secret-token');
|
||||
|
||||
const output = String(log.mock.calls[0]?.[0] ?? '');
|
||||
expect(output).not.toContain('password');
|
||||
expect(output).not.toContain('test-password-value');
|
||||
expect(output).not.toContain('secret-value');
|
||||
expect(output).not.toContain('secret-token');
|
||||
expect(output).toContain('[REDACTED]');
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user