webssh2-server
Version:
A Websocket to SSH2 gateway using xterm.js, socket.io, ssh2
248 lines (247 loc) • 5.66 kB
JavaScript
// app/utils/branded.ts
// Constructor functions and validators for branded types
// Constructors with validation
/**
* Create a SessionId from string
*/
export function createSessionId(id) {
if (id === '') {
throw new Error('SessionId cannot be empty');
}
return id;
}
/**
* Create a UserId from string
*/
export function createUserId(id) {
if (id === '') {
throw new Error('UserId cannot be empty');
}
return id;
}
/**
* Create an SshHost from string
*/
export function createSshHost(host) {
if (host === '') {
throw new Error('SSH host cannot be empty');
}
// Basic validation - could be more sophisticated
if (host.includes(' ')) {
throw new Error('SSH host cannot contain spaces');
}
return host;
}
/**
* Try to create an SshHost, returning null on invalid input
*/
export function trySshHost(host) {
if (host == null || host === '') {
return null;
}
try {
return createSshHost(host);
}
catch {
return null;
}
}
/**
* Create an SshPort from number
*/
export function createSshPort(port) {
if (!Number.isInteger(port) || port < 1 || port > 65535) {
throw new Error(`Invalid SSH port: ${port}`);
}
return port;
}
/**
* Try to create an SshPort, returning null on invalid input
*/
export function trySshPort(port) {
if (port == null) {
return null;
}
try {
return createSshPort(port);
}
catch {
return null;
}
}
/**
* Create a Username from string
*/
export function createUsername(username) {
if (username === '') {
throw new Error('Username cannot be empty');
}
return username;
}
/**
* Try to create a Username, returning null on invalid input
*/
export function tryUsername(username) {
if (username == null || username === '') {
return null;
}
return createUsername(username);
}
/**
* Create a Password from string
*/
export function createPassword(password) {
// Passwords can be empty in some auth scenarios
return password;
}
/**
* Create a PrivateKey from string
*/
export function createPrivateKey(key) {
if (key === '') {
throw new Error('Private key cannot be empty');
}
return key;
}
/**
* Create a TerminalType from string
*/
export function createTerminalType(term) {
if (term === '') {
throw new Error('Terminal type cannot be empty');
}
return term;
}
/**
* Try to create a TerminalType, returning null on invalid input
*/
export function tryTerminalType(term) {
if (term == null || term === '') {
return null;
}
return createTerminalType(term);
}
/**
* Create an EnvVarName from string
*/
export function createEnvVarName(name) {
if (name === '') {
throw new Error('Environment variable name cannot be empty');
}
if (!/^[A-Za-z_]\w*$/.test(name)) {
throw new Error(`Invalid environment variable name: ${name}`);
}
return name;
}
/**
* Create an EnvVarValue from string
*/
export function createEnvVarValue(value) {
return value;
}
/**
* Create an EventName from string
*/
export function createEventName(name) {
if (name === '') {
throw new Error('Event name cannot be empty');
}
return name;
}
/**
* Create a FilePath from string
*/
export function createFilePath(path) {
if (path === '') {
throw new Error('File path cannot be empty');
}
return path;
}
/**
* Create a UrlString from string
*/
export function createUrlString(url) {
if (url === '') {
throw new Error('URL cannot be empty');
}
try {
new URL(url);
}
catch {
throw new Error(`Invalid URL: ${url}`);
}
return url;
}
/**
* Create a CssColor from string
*/
export function createCssColor(color) {
if (color === '') {
throw new Error('CSS color cannot be empty');
}
// Basic validation - could validate against CSS color spec
return color;
}
/**
* Create SafeHtml from string (assumes it's been sanitized)
*/
export function createSafeHtml(html) {
// This should only be called after sanitization
return html;
}
/**
* Create a RegexPattern from string
*/
export function createRegexPattern(pattern) {
if (pattern === '') {
throw new Error('Regex pattern cannot be empty');
}
// Try to compile it to validate
// This is a validation function specifically for testing regex patterns
// The dynamic RegExp creation is intentional and safe as it's only for validation
try {
// eslint-disable-next-line security/detect-non-literal-regexp
new RegExp(pattern);
}
catch {
throw new Error(`Invalid regex pattern: ${pattern}`);
}
return pattern;
}
// Type guards
/**
* Check if value is a SessionId
*/
export function isSessionId(value) {
return typeof value === 'string' && value !== '';
}
/**
* Check if value is an SshHost
*/
export function isSshHost(value) {
return typeof value === 'string' && value !== '' && !value.includes(' ');
}
/**
* Check if value is an SshPort
*/
export function isSshPort(value) {
return typeof value === 'number' && Number.isInteger(value) && value >= 1 && value <= 65535;
}
/**
* Check if value is a Username
*/
export function isUsername(value) {
return typeof value === 'string' && value !== '';
}
/**
* Check if value is a Password
*/
export function isPassword(value) {
return typeof value === 'string';
}
/**
* Check if value is a TerminalType
*/
export function isTerminalType(value) {
return typeof value === 'string' && value !== '';
}