npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

ssh-terminal

v2.7.1

Published

SSH Terminal component based on xterm.js for multiple frontend frameworks

Readme

Vue SSH Terminal

Vue SSH Terminal là một component dựa trên xterm.js để sử dụng trong nhiều frontend khác nhau, cho phép kết nối SSH thông qua WebSocket.

Tính năng

  • 🆔 Computing ID Authentication: Kết nối thông qua LongVan Computing ID
  • 🔒 Zero Password: Không cần biết SSH password, server tự động lấy credentials
  • 🌐 WebSocket Connection: Kết nối SSH thông qua WebSocket an toàn
  • 🎯 Zero Configuration: Chỉ cần Computing ID và User Token
  • 🔧 Multi-Framework: Hỗ trợ Vue 2, Vue 3, và Web Component
  • 🎨 Customizable: Tùy chỉnh giao diện terminal (font, theme, cursor)
  • 📱 Responsive: Tự động resize terminal khi thay đổi kích thước cửa sổ

🔒 Tính Năng Bảo Mật Nâng Cao (v2.0+)

  • 🔐 Mandatory RSA Encryption: Bắt buộc mã hóa passwords - không hỗ trợ plaintext
  • 🚫 Legacy Auth Disabled: Hoàn toàn loại bỏ plaintext authentication
  • ✅ Input Validation: Xác thực nghiêm ngặt tất cả đầu vào
  • 🔍 Secure Logging: Không log thông tin nhạy cảm ra console
  • 📏 Message Size Validation: Kiểm tra kích thước message để tránh DoS
  • 🛡️ Error Sanitization: Thông báo lỗi không tiết lộ thông tin hệ thống
  • 🔒 Credentials Protection: Credentials không lộ trong DOM attributes
  • 🧹 Input Sanitization: Làm sạch dữ liệu đầu vào
  • ⚡ Fail-Fast Security: Ngắt kết nối ngay khi encryption fails

🚀 Universal Environment Support (v2.5+)

  • 🌐 Production-Ready Compatibility: Hoạt động hoàn hảo trên mọi HTTP và HTTPS environments
  • 🔧 Advanced Dual Encryption: Web Crypto API (HTTPS) + micro-rsa-dsa-dh (HTTP) với real RSA-OAEP
  • 🎨 Professional Clean UI: Giao diện production-ready, ẩn connection logs mặc định
  • 📦 Zero-Dependency Deployment: Tích hợp sẵn tất cả crypto libraries, không cần external CDN
  • ⚡ Intelligent Detection: Tự động chọn phương thức mã hóa tối ưu cho từng environment
  • 🛡️ Enterprise Security: Real encryption trong mọi môi trường, không có mock implementations

🚀 Tính Năng Khác

  • Production Bundle: Web component ~372KB (bao gồm enterprise-grade crypto libraries)
  • Auto-reconnection: Tự động kết nối lại khi mất connection với exponential backoff
  • Connection stability: Heartbeat mechanism để maintain WebSocket connection
  • Consistent CSS approach: Tất cả components sử dụng external CSS files

Cài đặt

npm install ssh-terminal

⚠️ Lưu ý quan trọng: Tất cả components đều yêu cầu import CSS file riêng để hiển thị đúng.

🚀 Quick Start

Computing ID (Recommended)

Cách nhanh nhất để kết nối với LongVan Computing instances:

Vue 2

<template>
  <SSHTerminal
    :computing-id="computingId"
    :user-token="userToken"
    :websocket-url="websocketUrl"
  />
</template>

<script>
import { SSHTerminal } from 'ssh-terminal/vue2';
import 'ssh-terminal/dist/vue2/ssh-terminal-vue2.css';

export default {
  components: {
    SSHTerminal
  },
  data() {
    return {
      computingId: '20.5109.3964',
      userToken: 'your-longvan-token',
      websocketUrl: 'wss://ssh-proxy.dev.longvan.vn'
    };
  }
};
</script>

Vue 3

<template>
  <SSHTerminal
    :computing-id="computingId"
    :user-token="userToken"
    :websocket-url="websocketUrl"
  />
</template>

<script setup>
import { ref } from 'vue';
import { SSHTerminal } from 'ssh-terminal/vue3';
import 'ssh-terminal/dist/vue3/ssh-terminal-vue3.css';

const computingId = ref('20.5109.3964');
const userToken = ref('your-longvan-token');
const websocketUrl = ref('wss://ssh-proxy.dev.longvan.vn');
</script>

JavaScript thuần

<!DOCTYPE html>
<html>
<head>
  <script type="module">
    import { SSHTerminalElement } from 'ssh-terminal';
    if (!customElements.get('ssh-terminal')) {
      customElements.define('ssh-terminal', SSHTerminalElement);
    }
  </script>
</head>
<body>
  <ssh-terminal id="terminal"></ssh-terminal>

  <script>
    const terminal = document.getElementById('terminal');

    // Cấu hình Computing ID
    terminal.setConfig({
      computingId: '20.5109.3964',
      userToken: 'your-longvan-token',
      wsUrl: 'wss://ssh-proxy.dev.longvan.vn'
    });

    // Lắng nghe sự kiện
    terminal.addEventListener('ready', () => {
      console.log('Connected to computing instance');
    });
  </script>
</body>
</html>

Sử dụng

Vue 3

<template>
  <div class="terminal-container">
    <!-- Computing ID Authentication -->
    <SSHTerminal
      :computing-id="computingId"
      :user-token="userToken"
      :websocket-url="websocketUrl"
      :options="options"
      @ready="onTerminalReady"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { SSHTerminal } from 'ssh-terminal/vue3';
import 'ssh-terminal/dist/vue3/ssh-terminal-vue3.css';

// Computing ID authentication
const computingId = ref('20.5109.3964');
const userToken = ref('your-longvan-token');
const websocketUrl = ref('wss://ssh-proxy.dev.longvan.vn');

const options = ref({
  fontSize: 14,
  theme: {
    background: '#1e1e1e',
    foreground: '#f0f0f0'
  }
});

function onTerminalReady(terminal) {
  // Terminal connected to computing instance
  console.log('Connected to computing:', computingId.value);
}
</script>

<style>
.terminal-container {
  width: 100%;
  height: 500px;
}
</style>

Web Component

npm install ssh-terminal
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>SSH Terminal - Computing ID</title>
  <script type="module">
    import { SSHTerminalElement } from 'ssh-terminal';
    if (!customElements.get('ssh-terminal')) {
      customElements.define('ssh-terminal', SSHTerminalElement);
    }
  </script>
  <style>
    .terminal-container {
      width: 800px;
      height: 500px;
      margin: 20px auto;
    }
  </style>
</head>
<body>
  <div class="terminal-container">
    <!-- Computing ID Authentication -->
    <ssh-terminal id="terminal"></ssh-terminal>
  </div>

  <script>
    // 🆔 Set Computing ID configuration
    const terminal = document.getElementById('terminal');
    terminal.setConfig({
      computingId: '20.5109.3964',
      userToken: 'your-longvan-token',
      wsUrl: 'wss://ssh-proxy.dev.longvan.vn'
    });

    terminal.addEventListener('ready', (event) => {
      console.log('Connected to computing instance');
    });
  </script>
</body>
</html>

Sử dụng trực tiếp từ CDN (không cần npm)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>SSH Terminal Example</title>
  <!-- Sử dụng từ unpkg CDN -->
  <script src="https://unpkg.com/[email protected]/dist/web-component/ssh-terminal.umd.js"></script>
  <!-- Hoặc sử dụng từ jsDelivr -->
  <!--
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/web-component/ssh-terminal.umd.js"></script>
  -->

  <!-- Lưu ý: Web component tự động inject CSS vào shadow DOM, không cần import CSS riêng -->
  <!-- Các phần tử helper của xterm.js sẽ được giữ trong shadow DOM của web component -->
  <style>
    .terminal-container {
      width: 800px;
      height: 500px;
      margin: 20px auto;
    }
  </style>
</head>
<body>
  <div class="terminal-container">
    <!-- ✅ Secure way (v2.0+) -->
    <ssh-terminal id="terminal" ws-url="wss://ssh-proxy.dev.longvan.vn"></ssh-terminal>
  </div>

  <script>
    // 🆔 Set Computing ID configuration
    const terminal = document.getElementById('terminal');
    terminal.setConfig({
      computingId: '20.5109.3964',
      userToken: 'your-longvan-token',
      wsUrl: 'wss://ssh-proxy.dev.longvan.vn'
    });

    terminal.addEventListener('ready', (event) => {
      console.log('Connected to computing instance');
    });
  </script>
</body>
</html>

Tải xuống và sử dụng trực tiếp

Bạn cũng có thể tải xuống file sau và sử dụng trực tiếp:

  • ssh-terminal.umd.js (CSS được inject tự động)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>SSH Terminal Example</title>
  <script src="path/to/ssh-terminal.umd.js"></script>
  <!-- CSS được inject tự động vào shadow DOM -->
  <style>
    .terminal-container {
      width: 800px;
      height: 500px;
      margin: 20px auto;
    }
  </style>
</head>
<body>
  <div class="terminal-container">
    <!-- ✅ Secure way (v2.0+) -->
    <ssh-terminal id="terminal"></ssh-terminal>
  </div>

  <script>
    // 🆔 Set Computing ID configuration
    const terminal = document.getElementById('terminal');
    terminal.setConfig({
      computingId: '20.5109.3964',
      userToken: 'your-longvan-token',
      wsUrl: 'wss://ssh-proxy.dev.longvan.vn'
    });

    terminal.addEventListener('ready', (event) => {
      console.log('Connected to computing instance');
    });
  </script>
</body>
</html>

🔧 Framework Integration

Nuxt 2

Plugin Setup

Tạo file plugins/ssh-terminal.client.js:

import Vue from 'vue'
import { Vue2SSHTerminal } from 'ssh-terminal/vue2'

// Register component globally (CSS tự động inject)
Vue.component('SSHTerminal', Vue2SSHTerminal)

Đăng ký plugin trong nuxt.config.js:

export default {
  plugins: [
    { src: '~/plugins/ssh-terminal.client.js', mode: 'client' }
  ]
}

Sử dụng trong component

<template>
  <div class="terminal-container">
    <SSHTerminal
      :computing-id="computingId"
      :user-token="userToken"
      :websocket-url="websocketUrl"
      @ready="onTerminalReady"
      @error="onTerminalError"
    />
  </div>
</template>

<script>
export default {
  data() {
    return {
      computingId: '20.5109.3964',
      userToken: 'your-longvan-token',
      websocketUrl: 'wss://ssh-proxy.dev.longvan.vn'
    }
  },
  methods: {
    onTerminalReady(terminal) {
      console.log('✅ Terminal ready!')
    },
    onTerminalError(error) {
      console.error('❌ Terminal error:', error)
    }
  }
}
</script>

<style scoped>
.terminal-container {
  width: 100%;
  height: 500px;
}
</style>

🆔 Computing ID Authentication

Kết nối SSH thông qua LongVan Computing ID - không cần biết SSH credentials.

Flow hoạt động:

  1. Client gửi Computing ID + User Token (encrypted)
  2. Server query LongVan GraphQL API để lấy SSH credentials
  3. Automatic SSH connection với credentials từ API
  4. Terminal ready - zero password approach

Ví dụ sử dụng:

// Mặc định: Clean UI (không hiển thị connection logs)
terminal.setConfig({
  computingId: '20.5109.3964',
  userToken: 'your-longvan-token',
  wsUrl: 'wss://ssh-proxy.dev.longvan.vn'
});

// Debug mode: Hiển thị connection logs
terminal.setConfig({
  computingId: '20.5109.3964',
  userToken: 'your-longvan-token',
  wsUrl: 'wss://ssh-proxy.dev.longvan.vn'
}, {
  showConnectionLogs: true
});

Ưu điểm:

  • Zero password approach - không cần biết SSH credentials
  • Tự động lấy thông tin từ LongVan GraphQL API
  • Token-based authentication
  • Secure encryption cho user token
  • Seamless user experience

API

Props (Vue Components)

| Prop | Kiểu dữ liệu | Bắt buộc | Validation | Mô tả | |------|--------------|----------|------------|-------| | computingId | String | Có | Valid computing ID format | LongVan Computing instance ID | | userToken | String | Có | Valid token format | LongVan user authentication token | | websocketUrl | String | Có | Valid WebSocket URL | URL của SSH Terminal server | | options | Object | Không | - | Các tùy chọn cho terminal |

Web Component Methods (v2.0+)

setConfig(config)

Secure method để set Computing ID configuration:

terminal.setConfig({
  computingId: '20.5109.3964',
  userToken: 'your-longvan-token',
  wsUrl: 'wss://ssh-proxy.dev.longvan.vn'
});

Parameters:

  • config.computingId (String, required): LongVan Computing instance ID
  • config.userToken (String, required): LongVan user authentication token (auto-encrypted with RSA)
  • config.wsUrl (String, required): SSH Terminal server WebSocket URL

Security Notes:

  • User token is automatically encrypted with RSA before transmission
  • No plaintext credentials are ever sent over the network
  • Server validates all inputs before processing

Events

| Event | Tham số | Mô tả | |-------|---------|-------| | ready | terminal | Được gọi khi terminal đã sẵn sàng, trả về đối tượng terminal | | error | { message, code } | Được gọi khi có lỗi xảy ra (authentication, connection, etc.) | | close | { code, reason } | Được gọi khi connection bị đóng | | computing-connected | { computingId, host, username } | Được gọi khi Computing ID authentication thành công (v2.0+) |

Terminal Options

| Option | Kiểu dữ liệu | Mặc định | Mô tả | |--------|--------------|----------|-------| | fontSize | Number | 14 | Kích thước font | | fontFamily | String | 'Menlo, Monaco, "Courier New", monospace' | Font family | | theme | Object | { background: '#000000', foreground: '#ffffff', ... } | Theme cho terminal | | cursorBlink | Boolean | true | Bật/tắt nhấp nháy con trỏ | | cursorStyle | String | 'block' | Kiểu con trỏ ('block', 'underline', 'bar') | | scrollback | Number | 1000 | Số dòng lưu trong bộ nhớ để cuộn lại | | reconnection | Object | {...} | Cấu hình auto-reconnection | | reconnection.enabled | Boolean | true | Bật/tắt auto-reconnection | | reconnection.maxAttempts | Number | 5 | Số lần thử kết nối lại tối đa | | reconnection.heartbeatInterval | Number | 30000 | Khoảng thời gian ping (ms) |

🐛 Troubleshooting

Vue Version Compatibility Issues

Error: TypeError: (0 , vue__WEBPACK_IMPORTED_MODULE_4__.openBlock) is not a function

Cause: Using Vue 3 APIs in Vue 2 environment or vice versa.

Solution: Use the correct version-specific import:

// ✅ For Vue 2 projects
import { SSHTerminal } from 'ssh-terminal/vue2';
import 'ssh-terminal/dist/vue2/ssh-terminal-vue2.css';

// ✅ For Vue 3 projects
import { SSHTerminal } from 'ssh-terminal/vue3';
import 'ssh-terminal/dist/vue3/ssh-terminal-vue3.css';

// ❌ Avoid generic import if you have version conflicts
import { Vue2SSHTerminal, Vue3SSHTerminal } from 'ssh-terminal';

Container Element Required Error

Error: Error: Container element is required

Cause: Terminal container element is not available when createTerminal is called.

Solution: Ensure the container element exists in DOM:

// ✅ Wait for element to be available
onMounted(() => {
  const container = terminalContainer.value;
  if (container) {
    initTerminal();
  }
});

// ✅ For Web Component, use setConfig() after element is connected
const terminal = document.getElementById('terminal');
if (terminal) {
  terminal.setConfig({
    computingId: '20.5109.3964',
    userToken: 'your-longvan-token',
    wsUrl: 'wss://ssh-proxy.dev.longvan.vn'
  });
}

CSS Not Loading

Problem: Terminal appears but styling is broken.

Solution: Make sure to import the CSS file:

// For Vue 2
import 'ssh-terminal/dist/vue2/ssh-terminal-vue2.css';

// For Vue 3
import 'ssh-terminal/dist/vue3/ssh-terminal-vue3.css';

// For generic build
import 'ssh-terminal/dist/ssh-terminal.css';

Đóng góp

Mọi đóng góp đều được chào đón! Vui lòng tạo issue hoặc pull request trên GitHub.

Giấy phép

MIT