From 9175b768873c068b05b267f4570adaa82d20cbda Mon Sep 17 00:00:00 2001
From: larabr <larabr+github@protonmail.com>
Date: Thu, 9 Feb 2023 23:07:27 +0100
Subject: [PATCH] Docs: clarify `Key.clone()` behaviour (#1589)

---
 src/key/key.js      |  8 ++++----
 test/general/key.js | 20 ++++++++++++++++++++
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/src/key/key.js b/src/key/key.js
index 130ff3d4..773fd0e2 100644
--- a/src/key/key.js
+++ b/src/key/key.js
@@ -170,13 +170,13 @@ class Key {
   }
 
   /**
-   * Clones the key object
-   * @param {Boolean} [deep=false] Whether to return a deep clone
+   * Clones the key object. The copy is shallow, as it references the same packet objects as the original. However, if the top-level API is used, the two key instances are effectively independent.
+   * @param {Boolean} [clonePrivateParams=false] Only relevant for private keys: whether the secret key paramenters should be deeply copied. This is needed if e.g. `encrypt()` is to be called either on the clone or the original key.
    * @returns {Promise<Key>} Clone of the key.
    */
-  clone(deep = false) {
+  clone(clonePrivateParams = false) {
     const key = new this.constructor(this.toPacketList());
-    if (deep) {
+    if (clonePrivateParams) {
       key.getKeys().forEach(k => {
         // shallow clone the key packets
         k.keyPacket = Object.create(
diff --git a/test/general/key.js b/test/general/key.js
index c22a75a4..e6e60a74 100644
--- a/test/general/key.js
+++ b/test/general/key.js
@@ -3236,6 +3236,26 @@ module.exports = () => describe('Key', function() {
     });
   });
 
+  it('clone() - removing users or their signatures does not affect the original key', async function() {
+    const key = await openpgp.readKey({ armoredKey: priv_key_rsa });
+    const keyClone = key.clone();
+    expect(key.users[0].selfCertifications.length > 0).to.be.true;
+    expect(keyClone.users[0].selfCertifications.length > 0).to.be.true;
+    keyClone.users[0].selfCertifications = [];
+    expect(key.users[0].selfCertifications.length > 0).to.be.true;
+    expect(keyClone.users[0].selfCertifications.length > 0).to.be.false;
+  });
+
+  it('clone() - removing subkeys or their signatures does not affect the original key', async function() {
+    const key = await openpgp.readKey({ armoredKey: priv_key_rsa });
+    const keyClone = key.clone(true);
+    expect(key.subkeys[0].bindingSignatures.length > 0).to.be.true;
+    expect(keyClone.subkeys[0].bindingSignatures.length > 0).to.be.true;
+    keyClone.subkeys[0].bindingSignatures = [];
+    expect(key.subkeys[0].bindingSignatures.length > 0).to.be.true;
+    expect(keyClone.subkeys[0].bindingSignatures.length > 0).to.be.false;
+  });
+
   it('revoke() - primary key', async function() {
     const privKey = await openpgp.decryptKey({
       privateKey: await openpgp.readKey({ armoredKey: priv_key_arm2 }),