mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2026-05-10 15:56:17 +02:00
302 lines
15 KiB
HTML
Executable File
302 lines
15 KiB
HTML
Executable File
{% extends "baseTemplate/index.html" %}
|
|
{% load i18n %}
|
|
{% block title %}{% trans "SSH and CageFS - CyberPanel" %}{% endblock %}
|
|
{% block content %}
|
|
|
|
{% load static %}
|
|
{% get_current_language as LANGUAGE_CODE %}
|
|
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
|
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.css">
|
|
<script src="https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.js"></script>
|
|
|
|
<style>
|
|
body {
|
|
background: #f6f8fa;
|
|
}
|
|
.ssh-access-panel, .ssh-access-panel * {
|
|
font-family: 'Inter', 'Segoe UI', Arial, sans-serif;
|
|
}
|
|
.ssh-access-panel {
|
|
width: 100%;
|
|
max-width: 1100px;
|
|
margin: 48px auto 0 auto;
|
|
background: linear-gradient(180deg, #fff 80%, #f6f8fa 100%);
|
|
border-radius: 18px;
|
|
box-shadow: 0 4px 32px #e0e7ef;
|
|
padding: 48px 48px 32px 48px;
|
|
position: relative;
|
|
border: 1px solid #e3e8ee;
|
|
}
|
|
#page-title h2 {
|
|
font-size: 2.1em;
|
|
color: #222b45;
|
|
font-weight: 700;
|
|
margin-bottom: 8px;
|
|
}
|
|
#page-title p {
|
|
color: #7b8190;
|
|
font-size: 1.08em;
|
|
margin-bottom: 24px;
|
|
}
|
|
.open-terminal-float {
|
|
position: absolute;
|
|
right: 48px;
|
|
top: 48px;
|
|
z-index: 2;
|
|
}
|
|
.open-terminal-float .btn-success {
|
|
padding: 13px 36px;
|
|
font-size: 1.13em;
|
|
font-weight: 700;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 8px #b2ebf2;
|
|
background: linear-gradient(90deg, #00b894 60%, #17a2b8 100%);
|
|
border: none;
|
|
transition: background 0.2s, box-shadow 0.2s;
|
|
}
|
|
.open-terminal-float .btn-success:hover {
|
|
background: linear-gradient(90deg, #17a2b8 60%, #00b894 100%);
|
|
box-shadow: 0 4px 16px #b2ebf2;
|
|
}
|
|
.panel {
|
|
background: none;
|
|
border: none;
|
|
box-shadow: none;
|
|
}
|
|
.panel-body {
|
|
padding: 0;
|
|
}
|
|
.title-hero {
|
|
font-size: 1.2em;
|
|
color: #2563eb;
|
|
font-weight: 600;
|
|
margin-bottom: 18px;
|
|
}
|
|
.form-group {
|
|
margin-bottom: 22px;
|
|
}
|
|
.form-control {
|
|
border-radius: 6px;
|
|
border: 1px solid #d1d5db;
|
|
font-size: 1.08em;
|
|
padding: 10px 12px;
|
|
}
|
|
.btn-primary, .btn-success {
|
|
min-width: 140px;
|
|
min-height: 48px;
|
|
padding: 0 32px;
|
|
border-radius: 6px;
|
|
font-weight: 600;
|
|
font-size: 1.08em;
|
|
box-shadow: 0 2px 8px #e3e8ee;
|
|
border: none;
|
|
transition: background 0.2s, box-shadow 0.2s;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
text-align: center;
|
|
line-height: 1.2;
|
|
}
|
|
.btn-primary {
|
|
background: linear-gradient(90deg, #2563eb 60%, #007bff 100%);
|
|
color: #fff;
|
|
}
|
|
.btn-primary:hover {
|
|
background: linear-gradient(90deg, #007bff 60%, #2563eb 100%);
|
|
box-shadow: 0 4px 16px #e3e8ee;
|
|
}
|
|
.btn-success {
|
|
background: linear-gradient(90deg, #00b894 60%, #17a2b8 100%);
|
|
color: #fff;
|
|
}
|
|
.btn-success:hover {
|
|
background: linear-gradient(90deg, #17a2b8 60%, #00b894 100%);
|
|
box-shadow: 0 4px 16px #b2ebf2;
|
|
}
|
|
.ssh-btn-row {
|
|
display: flex;
|
|
gap: 16px;
|
|
margin-top: 12px;
|
|
align-items: center;
|
|
}
|
|
.table {
|
|
background: #f8fafc;
|
|
border-radius: 8px;
|
|
overflow: hidden;
|
|
margin-bottom: 0;
|
|
}
|
|
.table th {
|
|
background: #f1f5f9;
|
|
color: #222b45;
|
|
font-weight: 700;
|
|
border: none;
|
|
}
|
|
.table td {
|
|
background: #fff;
|
|
color: #444;
|
|
border-top: 1px solid #e3e8ee;
|
|
}
|
|
.h4.text-danger.text-bold {
|
|
color: #e74c3c !important;
|
|
font-weight: 700;
|
|
font-size: 1.2em;
|
|
cursor: pointer;
|
|
}
|
|
.alert-warning {
|
|
border-radius: 8px;
|
|
font-size: 1em;
|
|
}
|
|
.btn.btn-border.btn-alt.border-red.btn-link.font-red {
|
|
border-radius: 6px;
|
|
font-weight: 600;
|
|
font-size: 1em;
|
|
}
|
|
.btn.btn-warning {
|
|
border-radius: 6px;
|
|
font-weight: 600;
|
|
font-size: 1em;
|
|
}
|
|
.table tbody tr:nth-child(even) {
|
|
@media (max-width: 1200px) {
|
|
.ssh-access-panel {
|
|
padding: 24px 8px 16px 8px;
|
|
}
|
|
.open-terminal-float {
|
|
right: 10px;
|
|
top: 10px;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<div class="ssh-access-panel">
|
|
<div ng-controller="sshAccess" class="panel">
|
|
<div id="page-title" style="display: flex; align-items: center; justify-content: space-between;">
|
|
<div>
|
|
<h2 class="ssh-access-title" style="margin-bottom: 0;">{% trans "SSH Access" %}</h2>
|
|
<p style="margin-top: 4px;">{% trans "Set up SSH access and enable/disable CageFS for " %} {{ domainName }}. {% trans " CageFS require CloudLinux OS." %}</p>
|
|
</div>
|
|
<div style="margin-left: 24px;">
|
|
<button type="button" class="btn btn-success" ng-click="openWebTerminal()" style="min-height: 48px; padding: 0 32px; font-size: 1.13em; font-weight: 700; border-radius: 8px; box-shadow: 0 2px 8px #b2ebf2; background: linear-gradient(90deg, #00b894 60%, #17a2b8 100%); border: none; transition: background 0.2s, box-shadow 0.2s; display: flex; align-items: center; justify-content: center;">
|
|
<span class="btn-content" style="display: flex; align-items: center; gap: 8px;"><span style="font-size: 1.2em;">🖥️</span> Open Terminal</span>
|
|
</button>
|
|
<div id="web-terminal-modal" class="modal fade" tabindex="-1" role="dialog">
|
|
<div class="modal-dialog modal-lg" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h4 class="modal-title">Web SSH Terminal</h4>
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
{% if not has_addons %}
|
|
<div style="background: #fff3cd; color: #856404; border: 1px solid #ffeeba; border-radius: 8px; padding: 18px; margin-bottom: 18px; text-align: center;">
|
|
<strong>This feature requires the CyberPanel Add-ons bundle.</strong><br>
|
|
<a href="https://cyberpanel.net/cyberpanel-addons" target="_blank" style="color: #2563eb; text-decoration: underline; font-weight: 600;">Learn more & upgrade</a>
|
|
</div>
|
|
<div style="position: relative; width: 100%; height: 400px;">
|
|
<div id="xterm-container" style="width:100%;height:400px;background:#000;"></div>
|
|
<div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255,255,255,0.85); display: flex; align-items: center; justify-content: center; z-index: 10; border-radius: 8px; font-size: 1.2em; color: #888; font-weight: 600;">
|
|
Web Terminal is disabled. Please upgrade to CyberPanel Add-ons to enable this feature.
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div id="xterm-container" style="width:100%;height:400px;background:#000;"></div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="panel-body">
|
|
{% if accessed_via_ip %}
|
|
<div class="alert alert-danger ssh-access-warning">
|
|
<strong>Notice:</strong> You are accessing CyberPanel via an <b>IP address</b>.<br>
|
|
The Web Terminal will not work when accessed via IP. Please issue a <b>hostname SSL</b> and access the panel using your hostname (with valid SSL) to enable the terminal.<br>
|
|
<a href="{{ ssl_issue_link }}" target="_blank" class="btn btn-warning" style="margin-top:10px;">Issue Hostname SSL</a>
|
|
</div>
|
|
{% endif %}
|
|
{% if is_selfsigned_ssl %}
|
|
<div class="alert alert-warning ssh-access-warning">
|
|
<strong>Warning:</strong> Your server is using a <b>self-signed SSL certificate</b> for the web terminal.<br>
|
|
For security and browser compatibility, please issue a valid hostname SSL certificate.<br>
|
|
<a href="{{ ssl_issue_link }}" target="_blank" class="btn btn-warning" style="margin-top:10px;">Issue SSL Now</a>
|
|
</div>
|
|
{% endif %}
|
|
<h3 class="title-hero">
|
|
{% trans "Set up SSH access for " %} {{ domainName }}.
|
|
<img ng-hide="wpInstallLoading" src="{% static 'images/loading.gif' %}"> -
|
|
<a target="_blank" href="https://go.cyberpanel.net/SFTPAccess" style="height: 23px;line-height: 21px;" class="btn btn-border btn-alt border-red btn-link font-red" title=""><span>SFTP Docs</span></a>
|
|
</h3>
|
|
<div class="example-box-wrapper">
|
|
<form name="websiteCreationForm" action="/" id="createPackages" class="form-horizontal bordered-row">
|
|
<div ng-hide="installationDetailsForm" class="form-group">
|
|
<label class="col-sm-3 control-label"></label>
|
|
<label class="col-sm-4 control-label">{% trans "SSH user for " %}
|
|
<span id="domainName">{{ domainName }}</span>
|
|
{% trans ' is ' %} <span id="externalApp">{{ externalApp }}</span></label>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label">{% trans "Password" %}</label>
|
|
<div class="col-sm-6">
|
|
<input type="password" class="form-control" ng-model="password" required>
|
|
</div>
|
|
</div>
|
|
<div ng-hide="installationDetailsForm" class="form-group">
|
|
<label class="col-sm-3 control-label"></label>
|
|
<div class="col-sm-4">
|
|
<button type="button" ng-click="setupSSHAccess()" class="btn btn-primary btn-lg btn-block">{% trans "Save Changes" %}</button>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="col-sm-12">
|
|
<form action="/" class="form-horizontal bordered-row">
|
|
<div class="form-group">
|
|
<div class="col-sm-12">
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>{% trans "User Name" %}</th>
|
|
<th>{% trans "Key" %}</th>
|
|
<th>{% trans "Delete" %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr ng-repeat="record in records track by $index">
|
|
<td ng-bind="record.userName">root</td>
|
|
<td ng-bind="record.key"></td>
|
|
<td ng-click="deleteKey(record.key)">
|
|
<div class="h4 text-danger text-bold">X</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div ng-hide="keyBox" class="form-group">
|
|
<div class="col-sm-12">
|
|
<textarea placeholder="Paste your public key here..." ng-model="keyData" rows="6" class="form-control">{{ logs }}</textarea>
|
|
</div>
|
|
</div>
|
|
<div ng-hide="showKeyBox" class="form-group">
|
|
<label class="col-sm-3 control-label"></label>
|
|
<div class="col-sm-4 ssh-btn-row">
|
|
<button type="button" ng-click="addKey()" class="btn btn-primary">{% trans "Add Key" %}</button>
|
|
</div>
|
|
</div>
|
|
<div ng-hide="saveKeyBtn" class="form-group">
|
|
<label class="col-sm-3 control-label"></label>
|
|
<div class="col-sm-4 ssh-btn-row">
|
|
<button type="button" ng-click="saveKey()" class="btn btn-primary">{% trans "Save" %}</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% endblock %} |