left4me/docs/superpowers/plans/2026-05-13-rcon-password-display-v1.md

4.4 KiB

RCON Password Display Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Show the RCON password on the server detail page with a show/hide toggle.

Architecture: Three-file change. An external JS file (password-reveal.js) provides the reveal/hide interaction via event delegation on [data-password-toggle] attributes — no inline handlers or HTML event attributes. The template adds a row to the existing .server-info definition list with a masked span, value span, and toggle button. Base.html adds the script include alongside existing JS files.

Tech Stack: Vanilla JS, Jinja2 templates, Flask


File Structure

File Responsibility
l4d2web/static/js/password-reveal.js New. Delegated click listener for show/hide toggle on [data-password-toggle]
l4d2web/templates/server_detail.html Add one <div> row to .server-info DL
l4d2web/templates/base.html Add <script src="...password-reveal.js">

Task 1: Create the reveal/hide JS

Files:

  • Create: l4d2web/static/js/password-reveal.js

  • Step 1: Create password-reveal.js

document.addEventListener('click', (e) => {
  const btn = e.target.closest('[data-password-toggle]');
  if (!btn) return;
  const id = btn.dataset.passwordToggle;
  const mask = document.querySelector(`[data-password-field="${id}"].password-mask`);
  const value = document.querySelector(`[data-password-field="${id}"].password-value`);
  if (!mask || !value) return;
  const hidden = value.hidden;
  value.hidden = !hidden;
  mask.hidden = hidden;
  btn.textContent = hidden ? 'hide' : 'show';
  btn.setAttribute('aria-label', hidden ? 'Hide RCON password' : 'Show RCON password');
});
  • Step 2: Verify the file exists

Run: ls -la l4d2web/static/js/password-reveal.js Expected: File exists, is about 450 bytes

  • Step 3: Commit
git add l4d2web/static/js/password-reveal.js
git commit -m "feat: add password reveal toggle JS"

Task 2: Add RCON password row to server detail template

Files:

  • Modify: l4d2web/templates/server_detail.html:13

  • Step 1: Add the RCON password row after the blueprint row

Insert after line 13 (</dd></div> for blueprint):

    <div><dt>RCON Password</dt><dd><span class="password-mask" data-password-field="{{ server.id }}">••••••••••••</span><span class="password-value" data-password-field="{{ server.id }}" hidden>{{ server.rcon_password }}</span> <button class="link-button" data-password-toggle="{{ server.id }}" aria-label="Show RCON password">show</button></dd></div>

Expected result: the .server-info DL now shows three rows: Port, Blueprint, RCON Password.

  • Step 2: Verify template renders

Run: python -c "from jinja2 import Environment; env=Environment(); env.parse(open('l4d2web/templates/server_detail.html').read()); print('parse ok')" Expected: parse ok

  • Step 3: Commit
git add l4d2web/templates/server_detail.html
git commit -m "feat: add RCON password row to server detail page"

Task 3: Include the script in base template

Files:

  • Modify: l4d2web/templates/base.html:44

  • Step 1: Add the script include

Insert after line 43 (<script src="...file-tree.js">):

    <script src="{{ url_for('static', filename='js/password-reveal.js') }}"></script>

Expected result: base.html now has 5 script includes: htmx, csrf.js, sse.js, modal.js, file-tree.js, password-reveal.js.

  • Step 2: Verify the app starts

Run: cd l4d2web && python -c "from l4d2web.app import create_app; app=create_app(); print('app created ok')" (or similar smoke test)

Expected: App initializes without import/template errors.

  • Step 3: Commit
git add l4d2web/templates/base.html
git commit -m "feat: include password-reveal.js in base template"

Task 4: Run tests

Files: None

  • Step 1: Run existing test suite

Run: pytest l4d2web/tests -q Expected: All tests pass (no regressions from this purely-presentational change)

  • Step 2: If any tests fail, investigate and fix

Run: pytest l4d2web/tests -q --tb=long Expected: Clear failure report to debug