From 419737d293052bbe62f75330dc20faaa3ee83398 Mon Sep 17 00:00:00 2001
From: SmithThe4th <gsmith@bitwarden.com>
Date: Tue, 29 Aug 2023 12:57:01 -0400
Subject: [PATCH] [PM-3155] CLI: Editing a cipher with a non-discoverable
 passkey causes the passkey to be removed (#6055)

* Added fido2keyexport for the CLI and added the fido2key field to the login response for the CLI

* Added fido2keyexport for the CLI and added the fido2key field to the login response for the CLI

* Removed unneccesary code

* Added non discoverable passkey to template
---
 .../src/models/export/fido2key.export.ts      | 91 +++++++++++++++++++
 libs/common/src/models/export/login.export.ts | 11 +++
 2 files changed, 102 insertions(+)
 create mode 100644 libs/common/src/models/export/fido2key.export.ts

diff --git a/libs/common/src/models/export/fido2key.export.ts b/libs/common/src/models/export/fido2key.export.ts
new file mode 100644
index 0000000000..764793114e
--- /dev/null
+++ b/libs/common/src/models/export/fido2key.export.ts
@@ -0,0 +1,91 @@
+import { EncString } from "../../platform/models/domain/enc-string";
+import { Fido2KeyView } from "../../vault/models/view/fido2-key.view";
+
+import { Fido2Key as Fido2KeyDomain } from "./../../vault/models/domain/fido2-key";
+
+export class Fido2KeyExport {
+  static template(): Fido2KeyExport {
+    const req = new Fido2KeyExport();
+    req.nonDiscoverableId = "keyId";
+    req.keyType = "keyType";
+    req.keyAlgorithm = "keyAlgorithm";
+    req.keyCurve = "keyCurve";
+    req.keyValue = "keyValue";
+    req.rpId = "rpId";
+    req.userHandle = "userHandle";
+    req.counter = "counter";
+    req.rpName = "rpName";
+    req.userName = "userName";
+    return req;
+  }
+
+  static toView(req: Fido2KeyExport, view = new Fido2KeyView()) {
+    view.nonDiscoverableId = req.nonDiscoverableId;
+    view.keyType = req.keyType as "public-key";
+    view.keyAlgorithm = req.keyAlgorithm as "ECDSA";
+    view.keyCurve = req.keyCurve as "P-256";
+    view.keyValue = req.keyValue;
+    view.rpId = req.rpId;
+    view.userHandle = req.userHandle;
+    view.counter = parseInt(req.counter);
+    view.rpName = req.rpName;
+    view.userName = req.userName;
+    return view;
+  }
+
+  static toDomain(req: Fido2KeyExport, domain = new Fido2KeyDomain()) {
+    domain.nonDiscoverableId =
+      req.nonDiscoverableId != null ? new EncString(req.nonDiscoverableId) : null;
+    domain.keyType = req.keyType != null ? new EncString(req.keyType) : null;
+    domain.keyAlgorithm = req.keyAlgorithm != null ? new EncString(req.keyAlgorithm) : null;
+    domain.keyCurve = req.keyCurve != null ? new EncString(req.keyCurve) : null;
+    domain.keyValue = req.keyValue != null ? new EncString(req.keyValue) : null;
+    domain.rpId = req.rpId != null ? new EncString(req.rpId) : null;
+    domain.userHandle = req.userHandle != null ? new EncString(req.userHandle) : null;
+    domain.counter = req.counter != null ? new EncString(req.counter) : null;
+    domain.rpName = req.rpName != null ? new EncString(req.rpName) : null;
+    domain.userName = req.userName != null ? new EncString(req.userName) : null;
+    return domain;
+  }
+
+  nonDiscoverableId: string;
+  keyType: string;
+  keyAlgorithm: string;
+  keyCurve: string;
+  keyValue: string;
+  rpId: string;
+  userHandle: string;
+  counter: string;
+  rpName: string;
+  userName: string;
+
+  constructor(o?: Fido2KeyView | Fido2KeyDomain) {
+    if (o == null) {
+      return;
+    }
+
+    if (o instanceof Fido2KeyView) {
+      this.nonDiscoverableId = o.nonDiscoverableId;
+      this.keyType = o.keyType;
+      this.keyAlgorithm = o.keyAlgorithm;
+      this.keyCurve = o.keyCurve;
+      this.keyValue = o.keyValue;
+      this.rpId = o.rpId;
+      this.userHandle = o.userHandle;
+      this.counter = String(o.counter);
+      this.rpName = o.rpName;
+      this.userName = o.userName;
+    } else {
+      this.nonDiscoverableId = o.nonDiscoverableId?.encryptedString;
+      this.keyType = o.keyType?.encryptedString;
+      this.keyAlgorithm = o.keyAlgorithm?.encryptedString;
+      this.keyCurve = o.keyCurve?.encryptedString;
+      this.keyValue = o.keyValue?.encryptedString;
+      this.rpId = o.rpId?.encryptedString;
+      this.userHandle = o.userHandle?.encryptedString;
+      this.counter = o.counter?.encryptedString;
+      this.rpName = o.rpName?.encryptedString;
+      this.userName = o.userName?.encryptedString;
+    }
+  }
+}
diff --git a/libs/common/src/models/export/login.export.ts b/libs/common/src/models/export/login.export.ts
index 7a22b12537..0e26def1fe 100644
--- a/libs/common/src/models/export/login.export.ts
+++ b/libs/common/src/models/export/login.export.ts
@@ -2,6 +2,7 @@ import { EncString } from "../../platform/models/domain/enc-string";
 import { Login as LoginDomain } from "../../vault/models/domain/login";
 import { LoginView } from "../../vault/models/view/login.view";
 
+import { Fido2KeyExport } from "./fido2key.export";
 import { LoginUriExport } from "./login-uri.export";
 
 export class LoginExport {
@@ -11,6 +12,7 @@ export class LoginExport {
     req.username = "jdoe";
     req.password = "myp@ssword123";
     req.totp = "JBSWY3DPEHPK3PXP";
+    req.fido2Key = Fido2KeyExport.template();
     return req;
   }
 
@@ -21,6 +23,9 @@ export class LoginExport {
     view.username = req.username;
     view.password = req.password;
     view.totp = req.totp;
+    if (req.fido2Key != null) {
+      view.fido2Key = Fido2KeyExport.toView(req.fido2Key);
+    }
     return view;
   }
 
@@ -31,6 +36,7 @@ export class LoginExport {
     domain.username = req.username != null ? new EncString(req.username) : null;
     domain.password = req.password != null ? new EncString(req.password) : null;
     domain.totp = req.totp != null ? new EncString(req.totp) : null;
+    //left out fido2Key for now
     return domain;
   }
 
@@ -38,6 +44,7 @@ export class LoginExport {
   username: string;
   password: string;
   totp: string;
+  fido2Key: Fido2KeyExport = null;
 
   constructor(o?: LoginView | LoginDomain) {
     if (o == null) {
@@ -52,6 +59,10 @@ export class LoginExport {
       }
     }
 
+    if (o.fido2Key != null) {
+      this.fido2Key = new Fido2KeyExport(o.fido2Key);
+    }
+
     if (o instanceof LoginView) {
       this.username = o.username;
       this.password = o.password;