Skip to content
Snippets Groups Projects
Select Git revision
  • b7d1f0f64fdec0b4fc08f14a6e9c158a0020e2b6
  • main default protected
  • next
  • renovate/main-lock-file-maintenance
  • renovate/main-lint-staged-16.x
  • renovate/main-redis-5.x
  • chore/update-static-data
  • feat/gnupg
  • fix/36615b-branch-reuse-no-cache
  • chore/punycode
  • refactor/pin-new-value
  • feat/36219--git-x509-signing
  • feat/structured-logger
  • hotfix/39.264.1
  • feat/skip-dangling
  • gh-readonly-queue/next/pr-36034-7a061c4ca1024a19e2c295d773d9642625d1c2be
  • hotfix/39.238.3
  • refactor/gitlab-auto-approve
  • feat/template-strings
  • gh-readonly-queue/next/pr-35654-137d934242c784e0c45d4b957362214f0eade1d7
  • fix/32307-global-extends-merging
  • 41.61.1
  • 41.61.0
  • 41.60.4
  • 41.60.3
  • 41.60.2
  • 41.60.1
  • 41.60.0
  • 41.59.2
  • 41.59.1
  • 41.59.0
  • 41.58.2
  • 41.58.1
  • 41.58.0
  • 41.57.1
  • 41.57.0
  • 41.56.1
  • 41.56.0
  • 41.55.3
  • 41.55.2
  • 41.55.1
41 results

index.spec.ts

Blame
  • private-key.spec.ts 4.86 KiB
    import os from 'node:os';
    import fs from 'fs-extra';
    import { any, mockDeep } from 'jest-mock-extended';
    import upath from 'upath';
    import { Fixtures } from '../../../test/fixtures';
    import { mockedExtended } from '../../../test/util';
    import * as exec_ from '../exec';
    import { configSigningKey, writePrivateKey } from './private-key';
    import { setPrivateKey } from '.';
    
    jest.mock('fs-extra', () =>
      jest
        .requireActual<
          typeof import('../../../test/fixtures')
        >('../../../test/fixtures')
        .fsExtra(),
    );
    jest.mock('../exec', () => mockDeep());
    
    const exec = mockedExtended(exec_);
    
    describe('util/git/private-key', () => {
      describe('writePrivateKey()', () => {
        beforeEach(() => {
          Fixtures.reset();
        });
    
        it('returns if no private key', async () => {
          await expect(writePrivateKey()).resolves.not.toThrow();
          await expect(configSigningKey('/tmp/some-repo')).resolves.not.toThrow();
        });
    
        it('throws error if failing', async () => {
          setPrivateKey('some-key');
          exec.exec.calledWith(any()).mockResolvedValue({ stdout: '', stderr: '' });
          exec.exec
            .calledWith(
              `gpg --import ${upath.join(os.tmpdir() + '/git-private-gpg.key')}`,
            )
            .mockRejectedValueOnce({
              stderr: `something wrong`,
              stdout: '',
            });
          await expect(writePrivateKey()).rejects.toThrow();
        });
    
        it('imports the private GPG key', async () => {
          const publicKey = 'BADC0FFEE';
          const repoDir = '/tmp/some-repo';
          exec.exec.calledWith(any()).mockResolvedValue({ stdout: '', stderr: '' });
          exec.exec
            .calledWith(
              `gpg --import ${upath.join(os.tmpdir() + '/git-private-gpg.key')}`,
            )
            .mockResolvedValueOnce({
              stderr: `gpg: key ${publicKey}: secret key imported\nfoo\n`,
              stdout: '',
            });
          setPrivateKey('some-key');
          await expect(writePrivateKey()).resolves.not.toThrow();
          await expect(configSigningKey(repoDir)).resolves.not.toThrow();
          expect(exec.exec).toHaveBeenCalledWith(
            `git config user.signingkey ${publicKey}`,
            { cwd: repoDir },
          );
          expect(exec.exec).toHaveBeenCalledWith('git config commit.gpgsign true', {
            cwd: repoDir,
          });
          expect(exec.exec).toHaveBeenCalledWith('git config gpg.format openpgp', {
            cwd: repoDir,
          });
        });
    
        it('does not import the key again', async () => {
          await expect(writePrivateKey()).resolves.not.toThrow();
          await expect(configSigningKey('/tmp/some-repo')).resolves.not.toThrow();
        });
    
        it('throws error if the private SSH key has a passphrase', async () => {
          const privateKeyFile = upath.join(os.tmpdir() + '/git-private-ssh.key');
          exec.exec.calledWith(any()).mockResolvedValue({ stdout: '', stderr: '' });
          exec.exec
            .calledWith(`ssh-keygen -y -P "" -f ${privateKeyFile}`)
            .mockRejectedValueOnce({
              stderr: `Load key "${privateKeyFile}": incorrect passphrase supplied to decrypt private key`,
              stdout: '',
            });
          setPrivateKey(`\
    -----BEGIN OPENSSH PRIVATE KEY-----
    some-private-key with-passphrase
    some-private-key with-passphrase
    -----END OPENSSH PRIVATE KEY-----
    `);
          await expect(writePrivateKey()).rejects.toThrow();
        });
    
        it('imports the private SSH key', async () => {
          const privateKey = `\
    -----BEGIN OPENSSH PRIVATE KEY-----
    some-private-key
    some-private-key
    -----END OPENSSH PRIVATE KEY-----
    `;
          const privateKeyFile = upath.join(os.tmpdir() + '/git-private-ssh.key');
          const publicKeyFile = `${privateKeyFile}.pub`;
          const publicKey = 'some-public-key';
          const repoDir = '/tmp/some-repo';
          exec.exec.calledWith(any()).mockResolvedValue({ stdout: '', stderr: '' });
          exec.exec
            .calledWith(`ssh-keygen -y -P "" -f ${privateKeyFile}`)
            .mockResolvedValue({
              stderr: '',
              stdout: publicKey,
            });
          setPrivateKey(privateKey);
          await expect(writePrivateKey()).resolves.not.toThrow();
          await expect(configSigningKey(repoDir)).resolves.not.toThrow();
          expect(exec.exec).toHaveBeenCalledWith(
            `git config user.signingkey ${privateKeyFile}`,
            { cwd: repoDir },
          );
          const privateKeyFileMode = (await fs.stat(privateKeyFile)).mode;
          expect((privateKeyFileMode & 0o777).toString(8)).toBe('600');
          expect((await fs.readFile(privateKeyFile)).toString()).toEqual(
            privateKey,
          );
          expect((await fs.readFile(publicKeyFile)).toString()).toEqual(publicKey);
          expect(exec.exec).toHaveBeenCalledWith('git config commit.gpgsign true', {
            cwd: repoDir,
          });
          expect(exec.exec).toHaveBeenCalledWith('git config gpg.format ssh', {
            cwd: repoDir,
          });
          process.emit('exit', 0);
          expect(fs.existsSync(privateKeyFile)).toBeFalse();
          expect(fs.existsSync(publicKeyFile)).toBeFalse();
        });
      });
    });