mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-09-10 17:45:42 +00:00
bbf839754e
Add multiple security hardenings across the server and web console: enforce proof-of-possession for /ws/bd-mgmt using Ed25519-signed headers with timestamp/nonce and replay protection (public key binding, canonicalization, storage, verification, and tests); remove legacy API key query param and config-table fallback in favor of scoped api_keys (migrate bootstrap key into api_keys); tighten WebSocket origin handling for relay and signal servers to allow only localhost origins by default unless an explicit allowlist is set; update auth middleware public paths and test helpers to use X-API-Key header; add ensureScopedAPIKey migration and related helpers; add a GitHub Secret Scan workflow and an audit report. Misc: propagate audit logging on bd-mgmt connect/disconnect and validate enrollment public keys during device register.
547 lines
29 KiB
HTML
547 lines
29 KiB
HTML
<%- include('layouts/main', {
|
|
title: typeof title !== 'undefined' ? title : 'Toolkit',
|
|
pageStyles: ['toolkit'],
|
|
pageScripts: ['toolkit'],
|
|
currentPage: 'toolkit',
|
|
breadcrumb: [{ label: _('nav.tools') }, { label: _('toolkit.title') }],
|
|
body: `
|
|
<div class="page-header">
|
|
<h1 class="page-title">
|
|
<span class="material-icons">handyman</span>
|
|
${_('toolkit.title')}
|
|
</h1>
|
|
<p class="page-subtitle">${_('toolkit.subtitle')}</p>
|
|
</div>
|
|
|
|
<!-- Tool category tabs -->
|
|
<div class="tab-bar">
|
|
<button class="tab-btn active" data-tab="network">
|
|
<span class="material-icons">language</span> ${_('toolkit.cat_network')}
|
|
</button>
|
|
<button class="tab-btn" data-tab="crypto">
|
|
<span class="material-icons">enhanced_encryption</span> ${_('toolkit.cat_crypto')}
|
|
</button>
|
|
<button class="tab-btn" data-tab="encoding">
|
|
<span class="material-icons">code</span> ${_('toolkit.cat_encoding')}
|
|
</button>
|
|
<button class="tab-btn" data-tab="system">
|
|
<span class="material-icons">terminal</span> ${_('toolkit.cat_system')}
|
|
</button>
|
|
</div>
|
|
|
|
<!-- ═══════════════════════════════════════════════════════════════════ -->
|
|
<!-- NETWORK TOOLS -->
|
|
<!-- ═══════════════════════════════════════════════════════════════════ -->
|
|
<div class="tab-panel active" id="tab-network">
|
|
<div class="tool-grid">
|
|
|
|
<!-- Ping -->
|
|
<div class="tool-card" id="tool-ping">
|
|
<div class="tool-card-header" data-toggle="tool-ping-body">
|
|
<span class="material-icons tool-icon">cell_tower</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.ping_title')}</h3>
|
|
<p>${_('toolkit.ping_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-ping-body">
|
|
<div class="tool-form">
|
|
<div class="form-row">
|
|
<div class="form-group flex-1">
|
|
<label class="form-label">${_('toolkit.host')}</label>
|
|
<input type="text" id="ping-host" class="form-input" placeholder="example.com" />
|
|
</div>
|
|
<button class="btn btn-primary tool-run-btn" id="ping-run">
|
|
<span class="material-icons">play_arrow</span> ${_('toolkit.run')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="tool-result" id="ping-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- TCP Port Check -->
|
|
<div class="tool-card" id="tool-tcp">
|
|
<div class="tool-card-header" data-toggle="tool-tcp-body">
|
|
<span class="material-icons tool-icon">electrical_services</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.tcp_title')}</h3>
|
|
<p>${_('toolkit.tcp_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-tcp-body">
|
|
<div class="tool-form">
|
|
<div class="form-row">
|
|
<div class="form-group flex-1">
|
|
<label class="form-label">${_('toolkit.host')}</label>
|
|
<input type="text" id="tcp-host" class="form-input" placeholder="example.com" />
|
|
</div>
|
|
<div class="form-group" style="width:120px">
|
|
<label class="form-label">${_('toolkit.port')}</label>
|
|
<input type="number" id="tcp-port" class="form-input" placeholder="443" min="1" max="65535" />
|
|
</div>
|
|
<button class="btn btn-primary tool-run-btn" id="tcp-run">
|
|
<span class="material-icons">play_arrow</span> ${_('toolkit.run')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="tool-result" id="tcp-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- SSL Certificate Inspector -->
|
|
<div class="tool-card" id="tool-ssl">
|
|
<div class="tool-card-header" data-toggle="tool-ssl-body">
|
|
<span class="material-icons tool-icon">verified_user</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.ssl_title')}</h3>
|
|
<p>${_('toolkit.ssl_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-ssl-body">
|
|
<div class="tool-form">
|
|
<div class="form-row">
|
|
<div class="form-group flex-1">
|
|
<label class="form-label">${_('toolkit.host')}</label>
|
|
<input type="text" id="ssl-host" class="form-input" placeholder="example.com" />
|
|
</div>
|
|
<div class="form-group" style="width:120px">
|
|
<label class="form-label">${_('toolkit.port')}</label>
|
|
<input type="number" id="ssl-port" class="form-input" placeholder="443" value="443" min="1" max="65535" />
|
|
</div>
|
|
<button class="btn btn-primary tool-run-btn" id="ssl-run">
|
|
<span class="material-icons">play_arrow</span> ${_('toolkit.run')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="tool-result" id="ssl-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- HTTP Health Check -->
|
|
<div class="tool-card" id="tool-http">
|
|
<div class="tool-card-header" data-toggle="tool-http-body">
|
|
<span class="material-icons tool-icon">http</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.http_title')}</h3>
|
|
<p>${_('toolkit.http_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-http-body">
|
|
<div class="tool-form">
|
|
<div class="form-row">
|
|
<div class="form-group flex-1">
|
|
<label class="form-label">URL</label>
|
|
<input type="text" id="http-url" class="form-input" placeholder="https://example.com" />
|
|
</div>
|
|
<button class="btn btn-primary tool-run-btn" id="http-run">
|
|
<span class="material-icons">play_arrow</span> ${_('toolkit.run')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="tool-result" id="http-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- DNS Lookup -->
|
|
<div class="tool-card" id="tool-dns">
|
|
<div class="tool-card-header" data-toggle="tool-dns-body">
|
|
<span class="material-icons tool-icon">dns</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.dns_title')}</h3>
|
|
<p>${_('toolkit.dns_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-dns-body">
|
|
<div class="tool-form">
|
|
<div class="form-row">
|
|
<div class="form-group flex-1">
|
|
<label class="form-label">${_('toolkit.domain')}</label>
|
|
<input type="text" id="dns-domain" class="form-input" placeholder="example.com" />
|
|
</div>
|
|
<button class="btn btn-primary tool-run-btn" id="dns-run">
|
|
<span class="material-icons">play_arrow</span> ${_('toolkit.run')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="tool-result" id="dns-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Whois / DNS Records -->
|
|
<div class="tool-card" id="tool-whois">
|
|
<div class="tool-card-header" data-toggle="tool-whois-body">
|
|
<span class="material-icons tool-icon">travel_explore</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.whois_title')}</h3>
|
|
<p>${_('toolkit.whois_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-whois-body">
|
|
<div class="tool-form">
|
|
<div class="form-row">
|
|
<div class="form-group flex-1">
|
|
<label class="form-label">${_('toolkit.domain')}</label>
|
|
<input type="text" id="whois-domain" class="form-input" placeholder="example.com" />
|
|
</div>
|
|
<button class="btn btn-primary tool-run-btn" id="whois-run">
|
|
<span class="material-icons">play_arrow</span> ${_('toolkit.run')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="tool-result" id="whois-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Speed Test -->
|
|
<div class="tool-card" id="tool-speed">
|
|
<div class="tool-card-header" data-toggle="tool-speed-body">
|
|
<span class="material-icons tool-icon">speed</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.speed_title')}</h3>
|
|
<p>${_('toolkit.speed_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-speed-body">
|
|
<div class="tool-form">
|
|
<div class="form-row">
|
|
<button class="btn btn-primary tool-run-btn" id="speed-run">
|
|
<span class="material-icons">play_arrow</span> ${_('toolkit.run_speed_test')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="tool-result" id="speed-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Wake-on-LAN -->
|
|
<div class="tool-card" id="tool-wol">
|
|
<div class="tool-card-header" data-toggle="tool-wol-body">
|
|
<span class="material-icons tool-icon">power_settings_new</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.wol_title')}</h3>
|
|
<p>${_('toolkit.wol_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-wol-body">
|
|
<div class="tool-form">
|
|
<div class="form-row">
|
|
<div class="form-group flex-1">
|
|
<label class="form-label">${_('toolkit.mac_address')}</label>
|
|
<input type="text" id="wol-mac" class="form-input" placeholder="AA:BB:CC:DD:EE:FF" />
|
|
</div>
|
|
<div class="form-group" style="width:180px">
|
|
<label class="form-label">${_('toolkit.broadcast')}</label>
|
|
<input type="text" id="wol-broadcast" class="form-input" placeholder="255.255.255.255" />
|
|
</div>
|
|
<button class="btn btn-primary tool-run-btn" id="wol-run">
|
|
<span class="material-icons">play_arrow</span> ${_('toolkit.send')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="tool-result" id="wol-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ═══════════════════════════════════════════════════════════════════ -->
|
|
<!-- CRYPTO TOOLS -->
|
|
<!-- ═══════════════════════════════════════════════════════════════════ -->
|
|
<div class="tab-panel" id="tab-crypto">
|
|
<div class="tool-grid">
|
|
|
|
<!-- Hash Generator -->
|
|
<div class="tool-card" id="tool-hash">
|
|
<div class="tool-card-header" data-toggle="tool-hash-body">
|
|
<span class="material-icons tool-icon">fingerprint</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.hash_title')}</h3>
|
|
<p>${_('toolkit.hash_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-hash-body">
|
|
<div class="tool-form">
|
|
<div class="form-group">
|
|
<label class="form-label">${_('toolkit.algorithm')}</label>
|
|
<div class="chip-group">
|
|
<button class="chip active" data-algo="md5">MD5</button>
|
|
<button class="chip" data-algo="sha1">SHA-1</button>
|
|
<button class="chip" data-algo="sha256">SHA-256</button>
|
|
<button class="chip" data-algo="sha512">SHA-512</button>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">${_('toolkit.input_text')}</label>
|
|
<textarea id="hash-input" class="form-input" rows="3" placeholder="${_('toolkit.enter_text')}"></textarea>
|
|
</div>
|
|
<button class="btn btn-primary tool-run-btn" id="hash-run">
|
|
<span class="material-icons">play_arrow</span> ${_('toolkit.generate')}
|
|
</button>
|
|
</div>
|
|
<div class="tool-result" id="hash-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Password Generator -->
|
|
<div class="tool-card" id="tool-password">
|
|
<div class="tool-card-header" data-toggle="tool-password-body">
|
|
<span class="material-icons tool-icon">password</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.password_title')}</h3>
|
|
<p>${_('toolkit.password_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-password-body">
|
|
<div class="tool-form">
|
|
<div class="form-row">
|
|
<div class="form-group" style="width:120px">
|
|
<label class="form-label">${_('toolkit.length')}</label>
|
|
<input type="number" id="pwd-length" class="form-input" value="20" min="4" max="128" />
|
|
</div>
|
|
<div class="form-group flex-1">
|
|
<label class="form-label">${_('toolkit.options')}</label>
|
|
<div class="check-row">
|
|
<label class="check-label"><input type="checkbox" id="pwd-upper" checked /> A-Z</label>
|
|
<label class="check-label"><input type="checkbox" id="pwd-lower" checked /> a-z</label>
|
|
<label class="check-label"><input type="checkbox" id="pwd-digits" checked /> 0-9</label>
|
|
<label class="check-label"><input type="checkbox" id="pwd-symbols" /> !@#$</label>
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-primary tool-run-btn" id="pwd-run">
|
|
<span class="material-icons">play_arrow</span> ${_('toolkit.generate')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="tool-result" id="pwd-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- JWT Decoder -->
|
|
<div class="tool-card" id="tool-jwt">
|
|
<div class="tool-card-header" data-toggle="tool-jwt-body">
|
|
<span class="material-icons tool-icon">token</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.jwt_title')}</h3>
|
|
<p>${_('toolkit.jwt_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-jwt-body">
|
|
<div class="tool-form">
|
|
<div class="form-group">
|
|
<label class="form-label">${_('toolkit.jwt_token')}</label>
|
|
<textarea id="jwt-input" class="form-input" rows="3" placeholder="eyJhbGciOiJIUzI1NiIs..."></textarea>
|
|
</div>
|
|
<button class="btn btn-primary tool-run-btn" id="jwt-run">
|
|
<span class="material-icons">play_arrow</span> ${_('toolkit.decode')}
|
|
</button>
|
|
</div>
|
|
<div class="tool-result" id="jwt-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ═══════════════════════════════════════════════════════════════════ -->
|
|
<!-- ENCODING TOOLS -->
|
|
<!-- ═══════════════════════════════════════════════════════════════════ -->
|
|
<div class="tab-panel" id="tab-encoding">
|
|
<div class="tool-grid">
|
|
|
|
<!-- Base64 -->
|
|
<div class="tool-card" id="tool-base64">
|
|
<div class="tool-card-header" data-toggle="tool-base64-body">
|
|
<span class="material-icons tool-icon">swap_horiz</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.base64_title')}</h3>
|
|
<p>${_('toolkit.base64_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-base64-body">
|
|
<div class="tool-form">
|
|
<div class="form-group">
|
|
<label class="form-label">${_('toolkit.input_text')}</label>
|
|
<textarea id="b64-input" class="form-input" rows="3" placeholder="${_('toolkit.enter_text')}"></textarea>
|
|
</div>
|
|
<div class="form-row">
|
|
<button class="btn btn-primary tool-run-btn" id="b64-encode">
|
|
<span class="material-icons">arrow_downward</span> ${_('toolkit.encode')}
|
|
</button>
|
|
<button class="btn btn-secondary tool-run-btn" id="b64-decode">
|
|
<span class="material-icons">arrow_upward</span> ${_('toolkit.decode')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="tool-result" id="b64-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- URL Encoder -->
|
|
<div class="tool-card" id="tool-urlencode">
|
|
<div class="tool-card-header" data-toggle="tool-urlencode-body">
|
|
<span class="material-icons tool-icon">link</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.url_title')}</h3>
|
|
<p>${_('toolkit.url_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-urlencode-body">
|
|
<div class="tool-form">
|
|
<div class="form-group">
|
|
<label class="form-label">${_('toolkit.input_text')}</label>
|
|
<textarea id="url-input" class="form-input" rows="3" placeholder="${_('toolkit.enter_text')}"></textarea>
|
|
</div>
|
|
<div class="form-row">
|
|
<button class="btn btn-primary tool-run-btn" id="url-encode">
|
|
<span class="material-icons">arrow_downward</span> ${_('toolkit.encode')}
|
|
</button>
|
|
<button class="btn btn-secondary tool-run-btn" id="url-decode">
|
|
<span class="material-icons">arrow_upward</span> ${_('toolkit.decode')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="tool-result" id="url-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ═══════════════════════════════════════════════════════════════════ -->
|
|
<!-- SYSTEM TOOLS -->
|
|
<!-- ═══════════════════════════════════════════════════════════════════ -->
|
|
<div class="tab-panel" id="tab-system">
|
|
<div class="tool-grid">
|
|
|
|
<!-- Process List -->
|
|
<div class="tool-card" id="tool-processes">
|
|
<div class="tool-card-header" data-toggle="tool-processes-body">
|
|
<span class="material-icons tool-icon">memory</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.processes_title')}</h3>
|
|
<p>${_('toolkit.processes_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-processes-body">
|
|
<div class="tool-form">
|
|
<button class="btn btn-primary tool-run-btn" id="proc-run">
|
|
<span class="material-icons">refresh</span> ${_('toolkit.refresh')}
|
|
</button>
|
|
</div>
|
|
<div class="tool-result" id="proc-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Disk Usage -->
|
|
<div class="tool-card" id="tool-disk">
|
|
<div class="tool-card-header" data-toggle="tool-disk-body">
|
|
<span class="material-icons tool-icon">storage</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.disk_title')}</h3>
|
|
<p>${_('toolkit.disk_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-disk-body">
|
|
<div class="tool-form">
|
|
<button class="btn btn-primary tool-run-btn" id="disk-run">
|
|
<span class="material-icons">refresh</span> ${_('toolkit.refresh')}
|
|
</button>
|
|
</div>
|
|
<div class="tool-result" id="disk-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Database Stats -->
|
|
<div class="tool-card" id="tool-db">
|
|
<div class="tool-card-header" data-toggle="tool-db-body">
|
|
<span class="material-icons tool-icon">dataset</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.db_title')}</h3>
|
|
<p>${_('toolkit.db_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-db-body">
|
|
<div class="tool-form">
|
|
<button class="btn btn-primary tool-run-btn" id="db-run">
|
|
<span class="material-icons">refresh</span> ${_('toolkit.refresh')}
|
|
</button>
|
|
</div>
|
|
<div class="tool-result" id="db-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Docker Containers -->
|
|
<div class="tool-card" id="tool-docker">
|
|
<div class="tool-card-header" data-toggle="tool-docker-body">
|
|
<span class="material-icons tool-icon">view_in_ar</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.docker_title')}</h3>
|
|
<p>${_('toolkit.docker_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-docker-body">
|
|
<div class="tool-form">
|
|
<button class="btn btn-primary tool-run-btn" id="docker-run">
|
|
<span class="material-icons">refresh</span> ${_('toolkit.refresh')}
|
|
</button>
|
|
</div>
|
|
<div class="tool-result" id="docker-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Log Viewer -->
|
|
<div class="tool-card" id="tool-logs">
|
|
<div class="tool-card-header" data-toggle="tool-logs-body">
|
|
<span class="material-icons tool-icon">article</span>
|
|
<div class="tool-meta">
|
|
<h3>${_('toolkit.logs_title')}</h3>
|
|
<p>${_('toolkit.logs_desc')}</p>
|
|
</div>
|
|
<span class="material-icons expand-icon">expand_more</span>
|
|
</div>
|
|
<div class="tool-card-body" id="tool-logs-body">
|
|
<div class="tool-form">
|
|
<div class="form-row">
|
|
<div class="form-group" style="width:160px">
|
|
<label class="form-label">${_('toolkit.source')}</label>
|
|
<select id="log-source" class="form-input">
|
|
<option value="console">${_('toolkit.log_console')}</option>
|
|
<option value="go">${_('toolkit.log_go')}</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group" style="width:120px">
|
|
<label class="form-label">${_('toolkit.lines')}</label>
|
|
<input type="number" id="log-lines" class="form-input" value="50" min="10" max="500" />
|
|
</div>
|
|
<button class="btn btn-primary tool-run-btn" id="log-run">
|
|
<span class="material-icons">refresh</span> ${_('toolkit.refresh')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="tool-result" id="log-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
` }) %>
|