feat(core): Add rsa option to ssh key generation (#7154)

PR adds a new field to the SourceControlPreferences as well as to the
POST parameters for the `source-control/preferences` and
`source-control/generate-key-pair` endpoints. Both now accept an
optional string parameter `keyGeneratorType` of `'ed25519' | 'rsa'`

Calling the `source-control/generate-key-pair` endpoint with the
parameter set, it will also update the stored preferences accordingly
(so that in the future new keys will use the same method)

By default ed25519 is being used. The default may be changed using a new
environment parameter:

`N8N_SOURCECONTROL_DEFAULT_SSH_KEY_TYPE` which can be `rsa` or `ed25519`

RSA keys are generated with a length of 4096 bytes.
This commit is contained in:
Michael Auerswald
2023-09-14 11:34:51 +02:00
committed by GitHub
parent aaf87c3edd
commit fdac2c8572
10 changed files with 82 additions and 10 deletions

View File

@@ -20,6 +20,7 @@ import { LoggerProxy } from 'n8n-workflow';
import { getLogger } from '@/Logger';
import { constants as fsConstants, accessSync } from 'fs';
import type { SourceControlledFile } from '@/environments/sourceControl/types/sourceControlledFile';
import type { SourceControlPreferences } from '@/environments/sourceControl/types/sourceControlPreferences';
const pushResult: SourceControlledFile[] = [
{
@@ -167,13 +168,21 @@ beforeAll(async () => {
describe('Source Control', () => {
it('should generate an SSH key pair', async () => {
const keyPair = await generateSshKeyPair();
const keyPair = await generateSshKeyPair('ed25519');
expect(keyPair.privateKey).toBeTruthy();
expect(keyPair.privateKey).toContain('BEGIN OPENSSH PRIVATE KEY');
expect(keyPair.publicKey).toBeTruthy();
expect(keyPair.publicKey).toContain('ssh-ed25519');
});
it('should generate an RSA key pair', async () => {
const keyPair = await generateSshKeyPair('rsa');
expect(keyPair.privateKey).toBeTruthy();
expect(keyPair.privateKey).toContain('BEGIN OPENSSH PRIVATE KEY');
expect(keyPair.publicKey).toBeTruthy();
expect(keyPair.publicKey).toContain('ssh-rsa');
});
it('should check for git and ssh folders and create them if required', async () => {
const userFolder = UserSettings.getUserN8nFolderPath();
const sshFolder = path.join(userFolder, SOURCE_CONTROL_SSH_FOLDER);
@@ -242,7 +251,7 @@ describe('Source Control', () => {
});
it('should class validate correct preferences', async () => {
const validPreferences = {
const validPreferences: Partial<SourceControlPreferences> = {
branchName: 'main',
repositoryUrl: 'git@example.com:n8ntest/n8n_testrepo.git',
branchReadOnly: false,