@@ -20,9 +20,25 @@ import { SessionCardAccountPage, SessionCardAddAnchor, SessionCardAddPage } from
2020import { SessionPasswordAccountPage , SessionPasswordAddAnchor , SessionPasswordAddPage } from "./password/mod.tsx" ;
2121import { SessionSeedAccountPage , SessionSeedAddAnchor , SessionSeedAddPage } from "./seed/mod.tsx" ;
2222import { SessionSolanaAccountPage , SessionSolanaAddAnchor , SessionSolanaAddPage } from "./solana/mod.tsx" ;
23+ import { SessionSshAccountPage , SessionSshAddAnchor , SessionSshAddPage } from "./ssh/mod.tsx" ;
2324
2425React ;
2526
27+ function getSshPublicKeySummary ( $entry : KDBX . Inner . KeePassFile . Entry ) {
28+ const publicKey = $entry . getDirectStringByKeyOrNull ( "SshPublicKey" ) ?. getValueOrThrow ( ) . get ( )
29+ if ( ! publicKey )
30+ return
31+
32+ const trimmed = publicKey . trim ( )
33+ if ( ! trimmed )
34+ return
35+
36+ if ( trimmed . length <= 48 )
37+ return trimmed
38+
39+ return `${ trimmed . slice ( 0 , 32 ) } ...${ trimmed . slice ( - 8 ) } `
40+ }
41+
2642export interface SessionData {
2743 readonly user : UserData
2844 readonly kdbx : KDBX . Database . Decrypted
@@ -190,6 +206,13 @@ export function SessionPage() {
190206 < Outline . SparklesIcon className = "size-5" />
191207 Seeds
192208 </ button >
209+ < button className = "bg-default-contrast aria-selected:bg-opposite aria-selected:text-opposite rounded-xl po-1 flex items-center gap-2 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-default-contrast aria-selected:focus-visible:outline-opposite"
210+ type = "button"
211+ aria-selected = { filter === "ssh" }
212+ onClick = { ( ) => filter === "ssh" ? setFilter ( undefined ) : setFilter ( "ssh" ) } >
213+ < Outline . KeyIcon className = "size-5" />
214+ SSH Keys
215+ </ button >
193216 < button className = "bg-default-contrast aria-selected:bg-opposite aria-selected:text-opposite rounded-xl po-1 flex items-center gap-2 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-default-contrast aria-selected:focus-visible:outline-opposite"
194217 type = "button"
195218 aria-selected = { filter === "trash" }
@@ -271,6 +294,9 @@ function SessionAccountCardInGrid(props: { $entry: KDBX.Inner.KeePassFile.Entry
271294 if ( type === "seed" )
272295 return < SessionSeedAccountPage $entry = { $entry } />
273296
297+ if ( type === "ssh" )
298+ return < SessionSshAccountPage $entry = { $entry } />
299+
274300 return null
275301 } ) ( ) }
276302 </ PathBoard > }
@@ -344,6 +370,9 @@ function SessionAccountCardInGrid(props: { $entry: KDBX.Inner.KeePassFile.Entry
344370 if ( type === "seed" )
345371 return $entry . getDirectStringByKeyOrNull ( "SeedPhrase" ) ?. getValueOrThrow ( ) . get ( ) . split ( " " ) . at ( 0 )
346372
373+ if ( type === "ssh" )
374+ return getSshPublicKeySummary ( $entry )
375+
347376 return null
348377 } ) ( ) }
349378 </ div >
@@ -394,6 +423,12 @@ function SessionAccountCardInGrid(props: { $entry: KDBX.Inner.KeePassFile.Entry
394423 Password
395424 </ div >
396425
426+ if ( type === "ssh" )
427+ return < div className = "bg-default-contrast rounded-xl po-1 flex items-center gap-2" >
428+ < Outline . KeyIcon className = "size-5" />
429+ SSH
430+ </ div >
431+
397432 return null
398433 } ) ( ) }
399434 </ div >
@@ -471,6 +506,9 @@ export function SessionAccountCard(props: { $entry: KDBX.Inner.KeePassFile.Entry
471506 if ( type === "seed" )
472507 return $entry . getDirectStringByKeyOrNull ( "SeedPhrase" ) ?. getValueOrThrow ( ) . get ( ) . split ( " " ) . at ( 0 )
473508
509+ if ( type === "ssh" )
510+ return getSshPublicKeySummary ( $entry )
511+
474512 return null
475513 } ) ( ) }
476514 </ div >
@@ -521,6 +559,12 @@ export function SessionAccountCard(props: { $entry: KDBX.Inner.KeePassFile.Entry
521559 Password
522560 </ div >
523561
562+ if ( type === "ssh" )
563+ return < div className = "bg-default-contrast rounded-xl po-1 flex items-center gap-2" >
564+ < Outline . KeyIcon className = "size-5" />
565+ SSH
566+ </ div >
567+
524568 return null
525569 } ) ( ) }
526570 </ div >
@@ -578,12 +622,17 @@ function SessionAccountAddMenu() {
578622 < PathBoard >
579623 < SessionSeedAddPage />
580624 </ PathBoard > }
625+ { hash . url . pathname === "/ssh" &&
626+ < PathBoard >
627+ < SessionSshAddPage />
628+ </ PathBoard > }
581629 </ SubpathProvider >
582630 < div className = "flex flex-col text-left gap-2" >
583631 < SessionPasswordAddAnchor />
584632 < SessionCryptoAddAnchor />
585633 < SessionCardAddAnchor />
586634 < SessionSeedAddAnchor />
635+ < SessionSshAddAnchor />
587636 </ div >
588637 </ Fragment >
589638}
@@ -859,4 +908,4 @@ export function AccountColorAnchor(props: { color?: Nullable<string> }) {
859908 data-color = { color } />
860909 </ InAnchor >
861910 </ a >
862- }
911+ }
0 commit comments