diff --git a/src/pages/terminal.astro b/src/pages/terminal.astro new file mode 100644 index 0000000..1390983 --- /dev/null +++ b/src/pages/terminal.astro @@ -0,0 +1,553 @@ +--- +// Heady Terminal Page - Alpine.js/Astro Remote Access 🤠 +// SSR-only: the page reads from `astro:content` collections that are +// populated at request time from headscale, so pre-rendering at build +// time hits empty/undefined data and throws. +export const prerender = false; + +import Layout from '../layouts/Layout.astro'; +import { getCollection } from 'astro:content'; +import GuacamoleLiteClient from '../components/GuacamoleLiteClient.astro'; +import NodeGrid from '../components/NodeGrid.astro'; +import SessionManager from '../components/SessionManager.astro'; + +// Fetch live data for terminal page with error handling +let allMachines = []; +let activeSessions = []; +let currentUser = null; + +try { + allMachines = await getCollection('machines'); + activeSessions = await getCollection('sessions', ({ data }) => data.status === 'active'); + const users = await getCollection('users'); + currentUser = users[0] || null; // In real app, get from auth +} catch (error) { + console.error('Error loading terminal page data:', error); + // Use fallback data for development +} + +// Filter online machines for terminal access +const onlineMachines = allMachines.filter(machine => machine.data?.online); + +// User permissions for protocol access +const userPermissions = { + ssh: true, + rdp: currentUser?.data.role === 'owner' || currentUser?.data.role === 'admin' || currentUser?.data.role === 'it_admin', + vnc: currentUser?.data.role === 'owner' || currentUser?.data.role === 'admin', + telnet: currentUser?.data.role !== 'member' && currentUser?.data.role !== 'auditor', + kubernetes: currentUser?.data.role === 'owner' || currentUser?.data.role === 'admin' || currentUser?.data.role === 'network_admin', + file_transfer: currentUser?.data.role !== 'member' && currentUser?.data.role !== 'auditor', + session_recording: currentUser?.data.role !== 'owner' +}; + +// Available protocols based on permissions +const availableProtocols = Object.entries(userPermissions) + .filter(([protocol, allowed]) => allowed && ['ssh', 'rdp', 'vnc', 'telnet', 'kubernetes'].includes(protocol)) + .map(([protocol]) => protocol); +--- + + +
+ +
+
+
+
+

+ 💻 + Heady Remote Access +

+

+ Secure multi-protocol terminal access to your VPN infrastructure +

+
+ + +
+
+ Role: + + {currentUser?.data.role} + +
+ + +
+
+
+
+ + +
+
+
+ +
+
+
+ + + +
+ +
+
+ + +
+ {availableProtocols.map(protocol => ( + + ))} +
+ + +
+ + +
+
+
+
+ +
+ +
+ +
+ + +
+
+

+ 🖥️ + Available Machines + +

+ + +
+ Sort by: + +
+
+ + +
+ +
+ + +
+
+
+

Machine List

+
+ +
+ +
+
+
+ + +
+ 🤠 +

No machines available

+

+ No machines match your search criteria. + No online machines support the selected protocol. +

+ +
+
+
+ + +
+
+
+ +
+
+ + + + +
+
+ +
+
+ +
+ + +
+
+ + +
+ +
+
+
+
+ + +
+
+

Quick Connect

+ +
+ +
+ + +
+ + +
+ +
+ {availableProtocols.map(protocol => ( + + ))} +
+
+ + +
+ + +
+
+
+
+
+ + +
\ No newline at end of file