diff --git a/api/utils/keys/hardwarekey/cliprompt.go b/api/utils/keys/hardwarekey/cliprompt.go index 64c6dfe2cae5e..56526c7f2b247 100644 --- a/api/utils/keys/hardwarekey/cliprompt.go +++ b/api/utils/keys/hardwarekey/cliprompt.go @@ -58,18 +58,33 @@ func NewCLIPrompt(w io.Writer, r prompt.StdinReader) *cliPrompt { // AskPIN prompts the user for a PIN. If the requirement is [PINOptional], // the prompt will offer the default PIN as a default value. -func (c *cliPrompt) AskPIN(ctx context.Context, requirement PINPromptRequirement, _ ContextualKeyInfo) (string, error) { - message := "Enter your YubiKey PIV PIN" +func (c *cliPrompt) AskPIN(ctx context.Context, requirement PINPromptRequirement, keyInfo ContextualKeyInfo) (string, error) { + msg := "Enter your YubiKey PIV PIN" + + // The user may need to set their PIN for the first time during login, + // give them a hint to continue to setting the PIN. if requirement == PINOptional { - message = "Enter your YubiKey PIV PIN [blank to use default PIN]" + msg += " [blank to use default PIN]" + } + + // If this is a hardware key agent request with command context info, + // include the command in the prompt. + if keyInfo.Command != "" { + msg = fmt.Sprintf("%v to continue with command %q", msg, keyInfo.Command) } - password, err := prompt.Password(ctx, c.writer, c.reader, message) + + password, err := prompt.Password(ctx, c.writer, c.reader, msg) return password, trace.Wrap(err) } // Touch prompts the user to touch the hardware key. -func (c *cliPrompt) Touch(_ context.Context, _ ContextualKeyInfo) error { - _, err := fmt.Fprintln(c.writer, "Tap your YubiKey") +func (c *cliPrompt) Touch(_ context.Context, keyInfo ContextualKeyInfo) error { + msg := "Tap your YubiKey" + if keyInfo.Command != "" { + msg = fmt.Sprintf("%v to continue with command %q", msg, keyInfo.Command) + } + + _, err := fmt.Fprintln(c.writer, msg) return trace.Wrap(err) } diff --git a/api/utils/keys/hardwarekey/hardwarekey.go b/api/utils/keys/hardwarekey/hardwarekey.go index 92121b233c1fc..6200c68830ceb 100644 --- a/api/utils/keys/hardwarekey/hardwarekey.go +++ b/api/utils/keys/hardwarekey/hardwarekey.go @@ -262,6 +262,8 @@ type ContextualKeyInfo struct { // metadata certificate format, to ensure the agent doesn't provide access to // non teleport client PIV keys. AgentKey bool + // Command is the running command utilizing this key. + Command string } // SignatureAlgorithm is a signature key algorithm option. diff --git a/api/utils/keys/hardwarekeyagent/agent.go b/api/utils/keys/hardwarekeyagent/agent.go index 44b4b06c92e87..4437bc9db14ee 100644 --- a/api/utils/keys/hardwarekeyagent/agent.go +++ b/api/utils/keys/hardwarekeyagent/agent.go @@ -102,6 +102,7 @@ func (s *agentService) Sign(ctx context.Context, req *hardwarekeyagentv1.SignReq Username: req.KeyInfo.Username, ClusterName: req.KeyInfo.ClusterName, AgentKey: true, + Command: req.Command, } var signerOpts crypto.SignerOpts diff --git a/api/utils/keys/hardwarekeyagent/service.go b/api/utils/keys/hardwarekeyagent/service.go index cde5b7b988b75..5129c3ae9440c 100644 --- a/api/utils/keys/hardwarekeyagent/service.go +++ b/api/utils/keys/hardwarekeyagent/service.go @@ -21,8 +21,11 @@ import ( "crypto" "crypto/rsa" "crypto/x509" + "fmt" "io" "log/slog" + "os" + "strings" "github.com/gravitational/trace" @@ -120,6 +123,13 @@ func (s *Service) agentSign(ctx context.Context, ref *hardwarekey.PrivateKeyRef, } } + // Trim leading path (/ or \ on windows) from command for user readability. + command := os.Args[0] + if i := strings.LastIndexAny(command, "/\\"); i != -1 { + command = command[i+1:] + } + commandString := fmt.Sprintf("%v %v", command, strings.Join(os.Args[1:], " ")) + req := &hardwarekeyagentv1.SignRequest{ Digest: digest, Hash: hash, @@ -136,7 +146,7 @@ func (s *Service) agentSign(ctx context.Context, ref *hardwarekey.PrivateKeyRef, Username: keyInfo.Username, ClusterName: keyInfo.ClusterName, }, - // TODO: Add command to sign request for prompt context. + Command: commandString, } resp, err := s.agentClient.Sign(ctx, req) diff --git a/gen/proto/go/teleport/lib/teleterm/v1/tshd_events_service.pb.go b/gen/proto/go/teleport/lib/teleterm/v1/tshd_events_service.pb.go index c74ff788e552b..9fc37293f2e23 100644 --- a/gen/proto/go/teleport/lib/teleterm/v1/tshd_events_service.pb.go +++ b/gen/proto/go/teleport/lib/teleterm/v1/tshd_events_service.pb.go @@ -965,10 +965,13 @@ func (x *PromptMFAResponse) GetTotpCode() string { // Request for PromptHardwareKeyPIN. type PromptHardwareKeyPINRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - RootClusterUri string `protobuf:"bytes,1,opt,name=root_cluster_uri,json=rootClusterUri,proto3" json:"root_cluster_uri,omitempty"` - // Specifies if a PIN is optional, allowing the user to set it up if left empty. - PinOptional bool `protobuf:"varint,2,opt,name=pin_optional,json=pinOptional,proto3" json:"pin_optional,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + // PinOptional specified if a PIN is optional, allowing the user to set it up if left empty. + PinOptional bool `protobuf:"varint,2,opt,name=pin_optional,json=pinOptional,proto3" json:"pin_optional,omitempty"` + // ProxyHostname is the proxy hostname of the client key. + ProxyHostname string `protobuf:"bytes,3,opt,name=proxy_hostname,json=proxyHostname,proto3" json:"proxy_hostname,omitempty"` + // Command is an optional command string to provide context for the prompt. + Command string `protobuf:"bytes,4,opt,name=command,proto3" json:"command,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1003,18 +1006,25 @@ func (*PromptHardwareKeyPINRequest) Descriptor() ([]byte, []int) { return file_teleport_lib_teleterm_v1_tshd_events_service_proto_rawDescGZIP(), []int{15} } -func (x *PromptHardwareKeyPINRequest) GetRootClusterUri() string { +func (x *PromptHardwareKeyPINRequest) GetPinOptional() bool { if x != nil { - return x.RootClusterUri + return x.PinOptional + } + return false +} + +func (x *PromptHardwareKeyPINRequest) GetProxyHostname() string { + if x != nil { + return x.ProxyHostname } return "" } -func (x *PromptHardwareKeyPINRequest) GetPinOptional() bool { +func (x *PromptHardwareKeyPINRequest) GetCommand() string { if x != nil { - return x.PinOptional + return x.Command } - return false + return "" } // Response for PromptHardwareKeyPIN. @@ -1065,10 +1075,13 @@ func (x *PromptHardwareKeyPINResponse) GetPin() string { // Request for PromptHardwareKeyTouchRequest. type PromptHardwareKeyTouchRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - RootClusterUri string `protobuf:"bytes,1,opt,name=root_cluster_uri,json=rootClusterUri,proto3" json:"root_cluster_uri,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + // ProxyHostname is the proxy hostname of the client key. + ProxyHostname string `protobuf:"bytes,2,opt,name=proxy_hostname,json=proxyHostname,proto3" json:"proxy_hostname,omitempty"` + // Command is an optional command string to provide context for the prompt. + Command string `protobuf:"bytes,3,opt,name=command,proto3" json:"command,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *PromptHardwareKeyTouchRequest) Reset() { @@ -1101,9 +1114,16 @@ func (*PromptHardwareKeyTouchRequest) Descriptor() ([]byte, []int) { return file_teleport_lib_teleterm_v1_tshd_events_service_proto_rawDescGZIP(), []int{17} } -func (x *PromptHardwareKeyTouchRequest) GetRootClusterUri() string { +func (x *PromptHardwareKeyTouchRequest) GetProxyHostname() string { if x != nil { - return x.RootClusterUri + return x.ProxyHostname + } + return "" +} + +func (x *PromptHardwareKeyTouchRequest) GetCommand() string { + if x != nil { + return x.Command } return "" } @@ -1147,10 +1167,11 @@ func (*PromptHardwareKeyTouchResponse) Descriptor() ([]byte, []int) { // Response for PromptHardwareKeyPINChange. type PromptHardwareKeyPINChangeRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - RootClusterUri string `protobuf:"bytes,1,opt,name=root_cluster_uri,json=rootClusterUri,proto3" json:"root_cluster_uri,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + // ProxyHostname is the proxy hostname of the client key. + ProxyHostname string `protobuf:"bytes,2,opt,name=proxy_hostname,json=proxyHostname,proto3" json:"proxy_hostname,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *PromptHardwareKeyPINChangeRequest) Reset() { @@ -1183,9 +1204,9 @@ func (*PromptHardwareKeyPINChangeRequest) Descriptor() ([]byte, []int) { return file_teleport_lib_teleterm_v1_tshd_events_service_proto_rawDescGZIP(), []int{19} } -func (x *PromptHardwareKeyPINChangeRequest) GetRootClusterUri() string { +func (x *PromptHardwareKeyPINChangeRequest) GetProxyHostname() string { if x != nil { - return x.RootClusterUri + return x.ProxyHostname } return "" } @@ -1257,10 +1278,11 @@ func (x *PromptHardwareKeyPINChangeResponse) GetPukChanged() bool { // Request for ConfirmHardwareKeySlotOverwrite. type ConfirmHardwareKeySlotOverwriteRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - RootClusterUri string `protobuf:"bytes,1,opt,name=root_cluster_uri,json=rootClusterUri,proto3" json:"root_cluster_uri,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` // Message to display in the prompt. - Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + // ProxyHostname is the proxy hostname of the client key. + ProxyHostname string `protobuf:"bytes,3,opt,name=proxy_hostname,json=proxyHostname,proto3" json:"proxy_hostname,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1295,16 +1317,16 @@ func (*ConfirmHardwareKeySlotOverwriteRequest) Descriptor() ([]byte, []int) { return file_teleport_lib_teleterm_v1_tshd_events_service_proto_rawDescGZIP(), []int{21} } -func (x *ConfirmHardwareKeySlotOverwriteRequest) GetRootClusterUri() string { +func (x *ConfirmHardwareKeySlotOverwriteRequest) GetMessage() string { if x != nil { - return x.RootClusterUri + return x.Message } return "" } -func (x *ConfirmHardwareKeySlotOverwriteRequest) GetMessage() string { +func (x *ConfirmHardwareKeySlotOverwriteRequest) GetProxyHostname() string { if x != nil { - return x.Message + return x.ProxyHostname } return "" } @@ -1630,25 +1652,27 @@ const file_teleport_lib_teleterm_v1_tshd_events_service_proto_rawDesc = "" + "\fdisplay_name\x18\x03 \x01(\tR\vdisplayName\x12!\n" + "\fredirect_url\x18\x04 \x01(\tR\vredirectUrl\"0\n" + "\x11PromptMFAResponse\x12\x1b\n" + - "\ttotp_code\x18\x01 \x01(\tR\btotpCode\"j\n" + - "\x1bPromptHardwareKeyPINRequest\x12(\n" + - "\x10root_cluster_uri\x18\x01 \x01(\tR\x0erootClusterUri\x12!\n" + - "\fpin_optional\x18\x02 \x01(\bR\vpinOptional\"0\n" + + "\ttotp_code\x18\x01 \x01(\tR\btotpCode\"\x99\x01\n" + + "\x1bPromptHardwareKeyPINRequest\x12!\n" + + "\fpin_optional\x18\x02 \x01(\bR\vpinOptional\x12%\n" + + "\x0eproxy_hostname\x18\x03 \x01(\tR\rproxyHostname\x12\x18\n" + + "\acommand\x18\x04 \x01(\tR\acommandJ\x04\b\x01\x10\x02R\x10root_cluster_uri\"0\n" + "\x1cPromptHardwareKeyPINResponse\x12\x10\n" + - "\x03pin\x18\x01 \x01(\tR\x03pin\"I\n" + - "\x1dPromptHardwareKeyTouchRequest\x12(\n" + - "\x10root_cluster_uri\x18\x01 \x01(\tR\x0erootClusterUri\" \n" + - "\x1ePromptHardwareKeyTouchResponse\"M\n" + - "!PromptHardwareKeyPINChangeRequest\x12(\n" + - "\x10root_cluster_uri\x18\x01 \x01(\tR\x0erootClusterUri\"i\n" + + "\x03pin\x18\x01 \x01(\tR\x03pin\"x\n" + + "\x1dPromptHardwareKeyTouchRequest\x12%\n" + + "\x0eproxy_hostname\x18\x02 \x01(\tR\rproxyHostname\x12\x18\n" + + "\acommand\x18\x03 \x01(\tR\acommandJ\x04\b\x01\x10\x02R\x10root_cluster_uri\" \n" + + "\x1ePromptHardwareKeyTouchResponse\"b\n" + + "!PromptHardwareKeyPINChangeRequest\x12%\n" + + "\x0eproxy_hostname\x18\x02 \x01(\tR\rproxyHostnameJ\x04\b\x01\x10\x02R\x10root_cluster_uri\"i\n" + "\"PromptHardwareKeyPINChangeResponse\x12\x10\n" + "\x03pin\x18\x01 \x01(\tR\x03pin\x12\x10\n" + "\x03puk\x18\x02 \x01(\tR\x03puk\x12\x1f\n" + "\vpuk_changed\x18\x03 \x01(\bR\n" + - "pukChanged\"l\n" + - "&ConfirmHardwareKeySlotOverwriteRequest\x12(\n" + - "\x10root_cluster_uri\x18\x01 \x01(\tR\x0erootClusterUri\x12\x18\n" + - "\amessage\x18\x02 \x01(\tR\amessage\"G\n" + + "pukChanged\"\x81\x01\n" + + "&ConfirmHardwareKeySlotOverwriteRequest\x12\x18\n" + + "\amessage\x18\x02 \x01(\tR\amessage\x12%\n" + + "\x0eproxy_hostname\x18\x03 \x01(\tR\rproxyHostnameJ\x04\b\x01\x10\x02R\x10root_cluster_uri\"G\n" + "'ConfirmHardwareKeySlotOverwriteResponse\x12\x1c\n" + "\tconfirmed\x18\x01 \x01(\bR\tconfirmed\"\"\n" + " GetUsageReportingSettingsRequest\"\x8f\x01\n" + diff --git a/gen/proto/ts/teleport/lib/teleterm/v1/tshd_events_service_pb.ts b/gen/proto/ts/teleport/lib/teleterm/v1/tshd_events_service_pb.ts index c94fc793af642..145834a1108db 100644 --- a/gen/proto/ts/teleport/lib/teleterm/v1/tshd_events_service_pb.ts +++ b/gen/proto/ts/teleport/lib/teleterm/v1/tshd_events_service_pb.ts @@ -332,15 +332,23 @@ export interface PromptMFAResponse { */ export interface PromptHardwareKeyPINRequest { /** - * @generated from protobuf field: string root_cluster_uri = 1; - */ - rootClusterUri: string; - /** - * Specifies if a PIN is optional, allowing the user to set it up if left empty. + * PinOptional specified if a PIN is optional, allowing the user to set it up if left empty. * * @generated from protobuf field: bool pin_optional = 2; */ pinOptional: boolean; + /** + * ProxyHostname is the proxy hostname of the client key. + * + * @generated from protobuf field: string proxy_hostname = 3; + */ + proxyHostname: string; + /** + * Command is an optional command string to provide context for the prompt. + * + * @generated from protobuf field: string command = 4; + */ + command: string; } /** * Response for PromptHardwareKeyPIN. @@ -362,9 +370,17 @@ export interface PromptHardwareKeyPINResponse { */ export interface PromptHardwareKeyTouchRequest { /** - * @generated from protobuf field: string root_cluster_uri = 1; + * ProxyHostname is the proxy hostname of the client key. + * + * @generated from protobuf field: string proxy_hostname = 2; */ - rootClusterUri: string; + proxyHostname: string; + /** + * Command is an optional command string to provide context for the prompt. + * + * @generated from protobuf field: string command = 3; + */ + command: string; } /** * Response for PromptHardwareKeyTouch. @@ -380,9 +396,11 @@ export interface PromptHardwareKeyTouchResponse { */ export interface PromptHardwareKeyPINChangeRequest { /** - * @generated from protobuf field: string root_cluster_uri = 1; + * ProxyHostname is the proxy hostname of the client key. + * + * @generated from protobuf field: string proxy_hostname = 2; */ - rootClusterUri: string; + proxyHostname: string; } /** * Response for PromptHardwareKeyPINChange. @@ -416,16 +434,18 @@ export interface PromptHardwareKeyPINChangeResponse { * @generated from protobuf message teleport.lib.teleterm.v1.ConfirmHardwareKeySlotOverwriteRequest */ export interface ConfirmHardwareKeySlotOverwriteRequest { - /** - * @generated from protobuf field: string root_cluster_uri = 1; - */ - rootClusterUri: string; /** * Message to display in the prompt. * * @generated from protobuf field: string message = 2; */ message: string; + /** + * ProxyHostname is the proxy hostname of the client key. + * + * @generated from protobuf field: string proxy_hostname = 3; + */ + proxyHostname: string; } /** * Response for ConfirmHardwareKeySlotOverwrite. @@ -1306,14 +1326,16 @@ export const PromptMFAResponse = new PromptMFAResponse$Type(); class PromptHardwareKeyPINRequest$Type extends MessageType { constructor() { super("teleport.lib.teleterm.v1.PromptHardwareKeyPINRequest", [ - { no: 1, name: "root_cluster_uri", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 2, name: "pin_optional", kind: "scalar", T: 8 /*ScalarType.BOOL*/ } + { no: 2, name: "pin_optional", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }, + { no: 3, name: "proxy_hostname", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: "command", kind: "scalar", T: 9 /*ScalarType.STRING*/ } ]); } create(value?: PartialMessage): PromptHardwareKeyPINRequest { const message = globalThis.Object.create((this.messagePrototype!)); - message.rootClusterUri = ""; message.pinOptional = false; + message.proxyHostname = ""; + message.command = ""; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -1323,12 +1345,15 @@ class PromptHardwareKeyPINRequest$Type extends MessageType { constructor() { super("teleport.lib.teleterm.v1.PromptHardwareKeyTouchRequest", [ - { no: 1, name: "root_cluster_uri", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + { no: 2, name: "proxy_hostname", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "command", kind: "scalar", T: 9 /*ScalarType.STRING*/ } ]); } create(value?: PartialMessage): PromptHardwareKeyTouchRequest { const message = globalThis.Object.create((this.messagePrototype!)); - message.rootClusterUri = ""; + message.proxyHostname = ""; + message.command = ""; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -1423,8 +1453,11 @@ class PromptHardwareKeyTouchRequest$Type extends MessageType { constructor() { super("teleport.lib.teleterm.v1.PromptHardwareKeyPINChangeRequest", [ - { no: 1, name: "root_cluster_uri", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + { no: 2, name: "proxy_hostname", kind: "scalar", T: 9 /*ScalarType.STRING*/ } ]); } create(value?: PartialMessage): PromptHardwareKeyPINChangeRequest { const message = globalThis.Object.create((this.messagePrototype!)); - message.rootClusterUri = ""; + message.proxyHostname = ""; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -1495,8 +1531,8 @@ class PromptHardwareKeyPINChangeRequest$Type extends MessageType { constructor() { super("teleport.lib.teleterm.v1.ConfirmHardwareKeySlotOverwriteRequest", [ - { no: 1, name: "root_cluster_uri", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 2, name: "message", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + { no: 2, name: "message", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: "proxy_hostname", kind: "scalar", T: 9 /*ScalarType.STRING*/ } ]); } create(value?: PartialMessage): ConfirmHardwareKeySlotOverwriteRequest { const message = globalThis.Object.create((this.messagePrototype!)); - message.rootClusterUri = ""; message.message = ""; + message.proxyHostname = ""; if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -1607,12 +1643,12 @@ class ConfirmHardwareKeySlotOverwriteRequest$Type extends MessageType {}, }; @@ -42,8 +43,9 @@ const hardwareKeyTouchDialog: DialogHardwareKeyTouch = { const hardwareKeyPinDialog: DialogHardwareKeyPin = { kind: 'hardware-key-pin', req: { - rootClusterUri: '/clusters/foo', + proxyHostname: 'foo.example.com', pinOptional: false, + command: '', }, onSuccess: () => {}, onCancel: () => {}, diff --git a/web/packages/teleterm/src/ui/ModalsHost/ModalsHost.test.tsx b/web/packages/teleterm/src/ui/ModalsHost/ModalsHost.test.tsx index f31667bc325d4..7411c0b43b9ad 100644 --- a/web/packages/teleterm/src/ui/ModalsHost/ModalsHost.test.tsx +++ b/web/packages/teleterm/src/ui/ModalsHost/ModalsHost.test.tsx @@ -43,7 +43,8 @@ const clusterConnectDialog: DialogClusterConnect = { const hardwareKeyTouchDialog: DialogHardwareKeyTouch = { kind: 'hardware-key-touch', req: { - rootClusterUri: '/clusters/foo', + proxyHostname: 'foo.example.com', + command: '', }, onCancel: () => {}, }; diff --git a/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/AskPin.tsx b/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/AskPin.tsx index a476b8f04189c..6201141307bbc 100644 --- a/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/AskPin.tsx +++ b/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/AskPin.tsx @@ -58,13 +58,19 @@ export function AskPin(props: { > - Enter your YubiKey PIV PIN. + Enter your YubiKey PIV PIN to continue + {props.req.command && ( + <> + {' with command:'} +
{props.req.command}
+ + )}
{props.req.pinOptional && 'To change the default PIN, leave the field blank.'} diff --git a/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/ChangePin.tsx b/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/ChangePin.tsx index 97b5b3e25dd4c..efd87cb6f9a5e 100644 --- a/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/ChangePin.tsx +++ b/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/ChangePin.tsx @@ -77,7 +77,7 @@ export function ChangePin(props: { }} > diff --git a/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/CommonHeader.tsx b/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/CommonHeader.tsx index fd41eaddaed6f..eabe3e5dec48f 100644 --- a/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/CommonHeader.tsx +++ b/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/CommonHeader.tsx @@ -20,18 +20,14 @@ import { ButtonIcon, H2 } from 'design'; import { DialogHeader } from 'design/Dialog'; import * as icons from 'design/Icon'; -import { RootClusterUri, routing } from 'teleterm/ui/uri'; - export function CommonHeader(props: { onCancel(): void; - rootClusterUri: RootClusterUri; + proxyHostname: string; }) { - const rootClusterName = routing.parseClusterName(props.rootClusterUri); - return (

- Unlock hardware key to access {rootClusterName} + Verify your identity on {props.proxyHostname}

diff --git a/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/Touch.tsx b/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/Touch.tsx index 389b129008056..c5ccd57db20ee 100644 --- a/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/Touch.tsx +++ b/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/Touch.tsx @@ -42,7 +42,7 @@ export function Touch(props: { > @@ -55,7 +55,15 @@ export function Touch(props: { `} > - Touch your YubiKey + + Touch your YubiKey to continue + {props.req.command && ( + <> + {' with command:'} +
{props.req.command}
+ + )} +
diff --git a/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/index.story.tsx b/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/index.story.tsx index 34e7418554c3c..6040c76ae88ee 100644 --- a/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/index.story.tsx +++ b/web/packages/teleterm/src/ui/ModalsHost/modals/HardwareKeys/index.story.tsx @@ -37,8 +37,9 @@ export function AskPinOptional() { onSuccess={() => {}} onCancel={() => {}} req={{ - rootClusterUri: rootCluster.uri, + proxyHostname: rootCluster.proxyHost, pinOptional: true, + command: '', }} /> ); @@ -50,8 +51,9 @@ export function AskPinRequired() { onSuccess={() => {}} onCancel={() => {}} req={{ - rootClusterUri: rootCluster.uri, + proxyHostname: rootCluster.proxyHost, pinOptional: false, + command: '', }} /> ); @@ -62,7 +64,8 @@ export function Touch() { {}} req={{ - rootClusterUri: rootCluster.uri, + proxyHostname: rootCluster.proxyHost, + command: '', }} /> ); @@ -73,7 +76,9 @@ export function ChangePin() { {}} onCancel={() => {}} - req={{ rootClusterUri: rootCluster.uri }} + req={{ + proxyHostname: rootCluster.proxyHost, + }} /> ); } @@ -84,7 +89,7 @@ export function OverwriteSlot() { onConfirm={() => {}} onCancel={() => {}} req={{ - rootClusterUri: rootCluster.uri, + proxyHostname: rootCluster.proxyHost, message: "Would you like to overwrite this slot's private key and certificate?", }}