344 lines
12 KiB
HTML
344 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>C-Relay Admin API</title>
|
|
<link rel="stylesheet" href="/api/index.css">
|
|
</head>
|
|
|
|
<body>
|
|
<h1>C-RELAY ADMIN API</h1>
|
|
|
|
<!-- Main Sections Wrapper -->
|
|
<div class="main-sections-wrapper">
|
|
|
|
<!-- Persistent Authentication Header - Always Visible -->
|
|
<div id="persistent-auth-container" class="section flex-section">
|
|
<div class="user-info-container">
|
|
<button type="button" id="login-logout-btn" class="login-logout-btn">LOGIN</button>
|
|
<div class="user-details" id="persistent-user-details" style="display: none;">
|
|
<div><strong>Name:</strong> <span id="persistent-user-name">Loading...</span></div>
|
|
<div><strong>Public Key:</strong>
|
|
<div class="user-pubkey" id="persistent-user-pubkey">Loading...</div>
|
|
</div>
|
|
<div><strong>About:</strong> <span id="persistent-user-about">Loading...</span></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Login Section -->
|
|
<div id="login-section" class="flex-section">
|
|
<div class="section">
|
|
<h2>NOSTR AUTHENTICATION</h2>
|
|
<p id="login-instructions">Please login with your Nostr identity to access the admin interface.</p>
|
|
<!-- nostr-lite login UI will be injected here -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Relay Connection Section -->
|
|
<div id="relay-connection-section" class="flex-section">
|
|
<div class="section">
|
|
<h2>RELAY CONNECTION</h2>
|
|
|
|
<div class="input-group">
|
|
<label for="relay-connection-url">Relay URL:</label>
|
|
<input type="text" id="relay-connection-url" value="ws://localhost:8888"
|
|
placeholder="ws://localhost:8888 or wss://relay.example.com">
|
|
</div>
|
|
|
|
<div class="input-group">
|
|
<label for="relay-pubkey-manual">Relay Pubkey (if not available via NIP-11):</label>
|
|
<input type="text" id="relay-pubkey-manual" placeholder="64-character hex pubkey"
|
|
pattern="[0-9a-fA-F]{64}" title="64-character hexadecimal public key">
|
|
|
|
</div>
|
|
|
|
<div class="inline-buttons">
|
|
<button type="button" id="connect-relay-btn">CONNECT TO RELAY</button>
|
|
<button type="button" id="disconnect-relay-btn" disabled>DISCONNECT</button>
|
|
<button type="button" id="test-websocket-btn" disabled>TEST WEBSOCKET</button>
|
|
</div>
|
|
|
|
<div class="status disconnected" id="relay-connection-status">NOT CONNECTED</div>
|
|
|
|
<!-- Relay Information Display -->
|
|
<div id="relay-info-display" class="hidden">
|
|
<h3>Relay Information (NIP-11)</h3>
|
|
<table class="config-table" id="relay-info-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Property</th>
|
|
<th>Value</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="relay-info-table-body">
|
|
</tbody>
|
|
</table>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div> <!-- End Main Sections Wrapper -->
|
|
|
|
|
|
|
|
|
|
<!-- Testing Section -->
|
|
<div id="div_config" class="section flex-section" style="display: none;">
|
|
<h2>RELAY CONFIGURATION</h2>
|
|
<div id="config-display" class="hidden">
|
|
<div class="config-table-container">
|
|
<table class="config-table" id="config-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Parameter</th>
|
|
<th>Value</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="config-table-body">
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="inline-buttons">
|
|
<button type="button" id="fetch-config-btn">REFRESH</button>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Auth Rules Management - Moved after configuration -->
|
|
<div class="section flex-section" id="authRulesSection" style="display: none;">
|
|
<div class="section-header">
|
|
<h2>AUTH RULES MANAGEMENT</h2>
|
|
</div>
|
|
|
|
<!-- Auth Rules Table -->
|
|
<div id="authRulesTableContainer" style="display: none;">
|
|
<table class="config-table" id="authRulesTable">
|
|
<thead>
|
|
<tr>
|
|
<th>Rule Type</th>
|
|
<th>Pattern Type</th>
|
|
<th>Pattern Value</th>
|
|
<th>Action</th>
|
|
<th>Status</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="authRulesTableBody">
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Simplified Auth Rule Input Section -->
|
|
<div id="authRuleInputSections" style="display: block;">
|
|
|
|
<!-- Combined Pubkey Auth Rule Section -->
|
|
|
|
|
|
<div class="input-group">
|
|
<label for="authRulePubkey">Pubkey (nsec or hex):</label>
|
|
<input type="text" id="authRulePubkey" placeholder="nsec1... or 64-character hex pubkey">
|
|
|
|
</div>
|
|
<div id="whitelistWarning" class="warning-box" style="display: none;">
|
|
<strong>⚠️ WARNING:</strong> Adding whitelist rules changes relay behavior to whitelist-only
|
|
mode.
|
|
Only whitelisted users will be able to interact with the relay.
|
|
</div>
|
|
<div class="inline-buttons">
|
|
<button type="button" id="addWhitelistBtn" onclick="addWhitelistRule()">ADD TO
|
|
WHITELIST</button>
|
|
<button type="button" id="addBlacklistBtn" onclick="addBlacklistRule()">ADD TO
|
|
BLACKLIST</button>
|
|
<button type="button" id="refreshAuthRulesBtn">REFRESH</button>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- DATABASE STATISTICS Section -->
|
|
<div class="section">
|
|
<div class="section-header">
|
|
<h2>DATABASE STATISTICS</h2>
|
|
</div>
|
|
|
|
|
|
<!-- Database Overview Table -->
|
|
<div class="input-group">
|
|
<label>Database Overview:</label>
|
|
<div class="config-table-container">
|
|
<table class="config-table" id="stats-overview-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Metric</th>
|
|
<th>Value</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="stats-overview-table-body">
|
|
<tr>
|
|
<td>Database Size</td>
|
|
<td id="db-size">-</td>
|
|
<td>Current database file size</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Total Events</td>
|
|
<td id="total-events">-</td>
|
|
<td>Total number of events stored</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Oldest Event</td>
|
|
<td id="oldest-event">-</td>
|
|
<td>Timestamp of oldest event</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Newest Event</td>
|
|
<td id="newest-event">-</td>
|
|
<td>Timestamp of newest event</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Event Kind Distribution Table -->
|
|
<div class="input-group">
|
|
<label>Event Kind Distribution:</label>
|
|
<div class="config-table-container">
|
|
<table class="config-table" id="stats-kinds-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Event Kind</th>
|
|
<th>Count</th>
|
|
<th>Percentage</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="stats-kinds-table-body">
|
|
<tr>
|
|
<td colspan="3" style="text-align: center; font-style: italic;">No data loaded</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Time-based Statistics Table -->
|
|
<div class="input-group">
|
|
<label>Time-based Statistics:</label>
|
|
<div class="config-table-container">
|
|
<table class="config-table" id="stats-time-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Period</th>
|
|
<th>Events</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="stats-time-table-body">
|
|
<tr>
|
|
<td>Last 24 Hours</td>
|
|
<td id="events-24h">-</td>
|
|
<td>Events in the last day</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Last 7 Days</td>
|
|
<td id="events-7d">-</td>
|
|
<td>Events in the last week</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Last 30 Days</td>
|
|
<td id="events-30d">-</td>
|
|
<td>Events in the last month</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Top Pubkeys Table -->
|
|
<div class="input-group">
|
|
<label>Top Pubkeys by Event Count:</label>
|
|
<div class="config-table-container">
|
|
<table class="config-table" id="stats-pubkeys-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Rank</th>
|
|
<th>Pubkey</th>
|
|
<th>Event Count</th>
|
|
<th>Percentage</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="stats-pubkeys-table-body">
|
|
<tr>
|
|
<td colspan="4" style="text-align: center; font-style: italic;">No data loaded</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Refresh Button -->
|
|
<div class="input-group">
|
|
<button type="button" id="refresh-stats-btn">REFRESH STATISTICS</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- NIP-17 DIRECT MESSAGES Section -->
|
|
<div class="section" id="nip17DMSection" style="display: none;">
|
|
<div class="section-header">
|
|
<h2>NIP-17 DIRECT MESSAGES</h2>
|
|
</div>
|
|
|
|
<!-- Outbox -->
|
|
<div class="input-group">
|
|
<label for="dm-outbox">Send Message to Relay:</label>
|
|
<textarea id="dm-outbox" rows="4" placeholder="Enter your message to send to the relay..."></textarea>
|
|
</div>
|
|
|
|
<!-- Send Button -->
|
|
<div class="input-group">
|
|
<button type="button" id="send-dm-btn">SEND MESSAGE</button>
|
|
</div>
|
|
|
|
<!-- Inbox -->
|
|
<div class="input-group">
|
|
<label>Received Messages from Relay:</label>
|
|
<div id="dm-inbox" class="log-panel" style="height: 200px;">
|
|
<div class="log-entry">No messages received yet.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Load the official nostr-tools bundle first -->
|
|
<!-- <script src="https://laantungir.net/nostr-login-lite/nostr.bundle.js"></script> -->
|
|
<script src="/api/nostr.bundle.js"></script>
|
|
|
|
<!-- Load NOSTR_LOGIN_LITE main library -->
|
|
<!-- <script src="https://laantungir.net/nostr-login-lite/nostr-lite.js"></script> -->
|
|
<script src="/api/nostr-lite.js"></script>
|
|
|
|
|
|
|
|
|
|
|
|
<script src="/api/index.js"></script>
|
|
</body>
|
|
|
|
</html> |