webssh2-server
Version:
A Websocket to SSH2 gateway using xterm.js, socket.io, ssh2
109 lines (108 loc) • 3.86 kB
JavaScript
/**
* State selectors for deriving data from session state
* All selectors are pure functions with no side effects
*/
/**
* Authentication selectors
*/
export const isAuthenticated = (state) => state.auth.status === 'authenticated';
export const isAuthPending = (state) => state.auth.status === 'pending';
export const hasAuthError = (state) => state.auth.status === 'failed';
export const getAuthError = (state) => state.auth.errorMessage;
export const getAuthMethod = (state) => state.auth.method;
export const getUsername = (state) => state.auth.username;
/**
* Connection selectors
*/
export const isConnected = (state) => state.connection.status === 'connected';
export const isConnecting = (state) => state.connection.status === 'connecting';
export const hasConnectionError = (state) => state.connection.status === 'error';
export const getConnectionError = (state) => state.connection.errorMessage;
export const getConnectionInfo = (state) => ({
host: state.connection.host,
port: state.connection.port,
status: state.connection.status,
connectionId: state.connection.connectionId
});
export const getConnectionStatus = (state) => state.connection.status;
/**
* Terminal selectors
*/
export const getTerminalDimensions = (state) => ({
rows: state.terminal.rows,
cols: state.terminal.cols
});
export const getTerminalType = (state) => state.terminal.term;
export const getTerminalEnvironment = (state) => state.terminal.environment;
export const getWorkingDirectory = (state) => state.terminal.cwd;
/**
* Combined selectors
*/
export const canExecuteCommands = (state) => isAuthenticated(state) && isConnected(state);
export const canResize = (state) => isConnected(state);
export const isSessionActive = (state) => isAuthenticated(state) && (isConnected(state) || isConnecting(state));
export const getSessionSummary = (state) => ({
id: state.id,
authenticated: isAuthenticated(state),
connected: isConnected(state),
username: getUsername(state),
host: state.connection.host,
port: state.connection.port,
terminal: getTerminalType(state),
dimensions: getTerminalDimensions(state)
});
/**
* Metadata selectors
*/
export const getSessionAge = (state) => Date.now() - state.metadata.createdAt;
export const getLastActivity = (state) => Math.max(state.metadata.updatedAt, state.connection.lastActivity);
export const getIdleTime = (state) => Date.now() - getLastActivity(state);
export const isIdle = (state, threshold = 300000) => getIdleTime(state) > threshold;
export const getClientInfo = (state) => ({
ip: state.metadata.clientIp,
userAgent: state.metadata.userAgent,
userId: state.metadata.userId
});
/**
* Error selectors
*/
export const getAllErrors = (state) => {
const errors = [];
if (state.auth.errorMessage !== null) {
errors.push(`Auth: ${state.auth.errorMessage}`);
}
if (state.connection.errorMessage !== null) {
errors.push(`Connection: ${state.connection.errorMessage}`);
}
return errors;
};
export const hasAnyError = (state) => hasAuthError(state) || hasConnectionError(state);
/**
* Status selectors
*/
export const getOverallStatus = (state) => {
if (state.connection.status === 'closed') {
return 'closed';
}
if (hasAnyError(state)) {
return 'error';
}
if (!isAuthenticated(state)) {
return 'authenticating';
}
if (!isConnected(state)) {
return 'connecting';
}
return 'ready';
};
/**
* Feature flag selectors (for gradual rollout)
*/
export const shouldUseNewAuth = (_state) => {
// Can be controlled per session or globally
return true; // Enable for all sessions for now
};
export const shouldUseConnectionPool = (_state) => {
// Can be controlled per session or globally
return true; // Enable for all sessions for now
};