{% extends "base.html" %} {% block title %}Dashboard · frp-jump{% endblock %} {% block content %}

Devices & tunnels

Wire up who can reach what. Changes apply next time each device's agent polls.

Devices

{% if devices %} {% for d in devices %} {% endfor %}
NameOwnerStatusEnrolledLast seenAgent
{{ d.name }} {{ d.owner_email }} {% if d.revoked %}revoked {% elif online[d.id] %}online {% else %}offline{% endif %} {{ d.enrolled_at.strftime("%Y-%m-%d") }} {{ d.last_seen_at.strftime("%Y-%m-%d %H:%M") if d.last_seen_at else "never" }} {{ d.agent_version or "—" }} {% if not d.revoked %}
{% endif %}
{% else %}

No devices enrolled yet.

{% endif %}

Add device

Leave name blank to let whoever redeems the token pick their own; set owner email to onboard a friend's first device under their own account instead of yours.

Pending enroll tokens

{% if pending_tokens %} {% for t in pending_tokens %} {% endfor %}
NameOwnerCreatedExpires
{{ t.device_name_hint or "(picked at enroll time)" }} {{ t.owner_email }} {{ t.created_at.strftime("%Y-%m-%d %H:%M") }} {{ t.expires_at.strftime("%Y-%m-%d %H:%M") }}
{% else %}

No unredeemed tokens.

{% endif %}

Services exposed

{% if services %} {% for s in services %} {% endfor %}
NameDeviceProtocolPort
{{ s.name }} {{ s.device_name }} {{ s.protocol.value }} {{ s.target_port }}
{% else %}

No services yet.

{% endif %} {% if devices %}

Add service

{% else %}

Add a device first.

{% endif %}

Access grants

{% if grants %} {% for g in grants %} {% endfor %}
ServiceExposed byGranted toStatus
{{ g.service_name }} {{ g.exposer_device_name }} {{ g.consumer_device_name }} {% if g.revoked %}revoked {% else %}active{% endif %} {% if not g.revoked %}
{% endif %}
{% else %}

No grants yet — nobody can reach anybody.

{% endif %} {% if services and devices %}

Grant access

{% else %}

Add a device and a service first.

{% endif %}

Users

{% for u in users %} {% endfor %}
EmailRoleDevices
{{ u.email }} {{ "admin" if u.is_admin else "user" }} {{ u.device_count }}
{% endblock %}