[Init] Initial commit - NetMesh terminal manager
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
This commit is contained in:
105
components/keychain/utils.ts
Normal file
105
components/keychain/utils.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* Keychain utility functions
|
||||
*/
|
||||
|
||||
import { BadgeCheck, Key } from 'lucide-react';
|
||||
import React from 'react';
|
||||
import { logger } from '../../lib/logger';
|
||||
import { KeyType, SSHKey } from '../../types';
|
||||
|
||||
/**
|
||||
* Get icon element for key source
|
||||
*/
|
||||
export const getKeyIcon = (key: SSHKey): React.ReactElement => {
|
||||
if (key.certificate) return React.createElement(BadgeCheck, { size: 16 });
|
||||
return React.createElement(Key, { size: 16 });
|
||||
};
|
||||
|
||||
/**
|
||||
* Get display text for key type
|
||||
*/
|
||||
export const getKeyTypeDisplay = (key: SSHKey, isMac: boolean): string => {
|
||||
void isMac;
|
||||
return key.type;
|
||||
};
|
||||
|
||||
/**
|
||||
* Detect key type from private key content
|
||||
*/
|
||||
export const detectKeyType = (privateKey: string): KeyType => {
|
||||
const pk = privateKey.toLowerCase();
|
||||
if (pk.includes('rsa')) return 'RSA';
|
||||
if (pk.includes('ecdsa') || pk.includes('ec ')) return 'ECDSA';
|
||||
return 'ED25519';
|
||||
};
|
||||
|
||||
/**
|
||||
* Copy text to clipboard
|
||||
*/
|
||||
export const copyToClipboard = async (text: string): Promise<boolean> => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
return true;
|
||||
} catch (err) {
|
||||
logger.error('Failed to copy to clipboard:', err);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if running on macOS
|
||||
*/
|
||||
export const isMacOS = (): boolean => {
|
||||
return navigator.platform.toLowerCase().includes('mac') ||
|
||||
navigator.userAgent.toLowerCase().includes('mac');
|
||||
};
|
||||
|
||||
// Panel modes type
|
||||
export type PanelMode =
|
||||
| { type: 'closed' }
|
||||
| { type: 'view'; key: SSHKey }
|
||||
| { type: 'edit'; key: SSHKey }
|
||||
| { type: 'generate'; keyType: 'standard' }
|
||||
| { type: 'import' }
|
||||
| { type: 'identity'; identity?: import('../../types').Identity }
|
||||
| { type: 'export'; key: SSHKey };
|
||||
|
||||
interface IdentitySectionVisibilityOptions {
|
||||
identityCount: number;
|
||||
filteredIdentityCount: number;
|
||||
filteredKeyCount: number;
|
||||
search: string;
|
||||
}
|
||||
|
||||
/** Show identities whenever any exist; while searching, keep the section if it matches or nothing matches. */
|
||||
export const shouldShowIdentitySection = ({
|
||||
identityCount,
|
||||
filteredIdentityCount,
|
||||
filteredKeyCount,
|
||||
search,
|
||||
}: IdentitySectionVisibilityOptions): boolean => {
|
||||
if (identityCount === 0) return false;
|
||||
if (!search.trim()) return true;
|
||||
|
||||
return filteredIdentityCount > 0 || filteredKeyCount === 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Show keys when any match (or exist while browsing). Hide the empty-key CTA when
|
||||
* identities alone already fill the page - including identity-only vaults.
|
||||
*/
|
||||
export const shouldShowKeySection = ({
|
||||
identityCount,
|
||||
filteredKeyCount,
|
||||
}: Pick<
|
||||
IdentitySectionVisibilityOptions,
|
||||
'identityCount' | 'filteredKeyCount' | 'search'
|
||||
>): boolean => {
|
||||
return filteredKeyCount > 0 || identityCount === 0;
|
||||
};
|
||||
|
||||
export const shouldShowSearchNoResults = (
|
||||
search: string,
|
||||
filteredItemCount: number,
|
||||
totalItemCount: number,
|
||||
): boolean => Boolean(search.trim()) && totalItemCount > 0 && filteredItemCount === 0;
|
||||
Reference in New Issue
Block a user