Save RDP Passwords in state as base64
CI / Build & Test (push) Successful in 3m24s

This commit is contained in:
Raven Scott
2026-02-28 19:12:05 -05:00
parent f3cad8f125
commit ee383a1173
2 changed files with 12 additions and 6 deletions
+1 -1
View File
@@ -1862,7 +1862,7 @@
<input type="text" id="rdpConnUsername" class="input" placeholder="Administrator" autocomplete="off"> <input type="text" id="rdpConnUsername" class="input" placeholder="Administrator" autocomplete="off">
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="form-label" for="rdpConnPassword">Password (optional, not saved)</label> <label class="form-label" for="rdpConnPassword">Password (optional)</label>
<input type="password" id="rdpConnPassword" class="input" placeholder="••••••••" autocomplete="new-password"> <input type="password" id="rdpConnPassword" class="input" placeholder="••••••••" autocomplete="new-password">
</div> </div>
<input type="hidden" id="rdpConnEditId"> <input type="hidden" id="rdpConnEditId">
+11 -5
View File
@@ -223,9 +223,11 @@ function generateRdpId() {
} }
function saveRdpConnections(cb) { function saveRdpConnections(cb) {
// Strip password before persisting — passwords are session-only // Encode password as base64 before persisting so it survives page reloads
const toSave = rdpConnections.map(c => { const toSave = rdpConnections.map(c => {
const { password, ...rest } = c; // eslint-disable-line no-unused-vars const { password, ...rest } = c; // eslint-disable-line no-unused-vars
if (password) rest.passwordB64 = btoa(unescape(encodeURIComponent(password)));
else delete rest.passwordB64;
return rest; return rest;
}); });
chrome.runtime.sendMessage( chrome.runtime.sendMessage(
@@ -324,7 +326,7 @@ function openAddRdpModal(conn) {
$('rdpConnWidth').value = conn ? (conn.width || 1280) : 1280; $('rdpConnWidth').value = conn ? (conn.width || 1280) : 1280;
$('rdpConnHeight').value = conn ? (conn.height || 720) : 720; $('rdpConnHeight').value = conn ? (conn.height || 720) : 720;
$('rdpConnUsername').value = conn ? (conn.username || '') : ''; $('rdpConnUsername').value = conn ? (conn.username || '') : '';
$('rdpConnPassword').value = ''; $('rdpConnPassword').value = conn ? (conn.password || '') : '';
$('rdpConnEditId').value = conn ? conn.id : ''; $('rdpConnEditId').value = conn ? conn.id : '';
$('rdpConnSubmit').textContent = isEdit ? 'Save Changes' : 'Save Connection'; $('rdpConnSubmit').textContent = isEdit ? 'Save Changes' : 'Save Connection';
@@ -1581,12 +1583,16 @@ async function refresh() {
}); });
renderSshGrid(); renderSshGrid();
} }
// Sync RDP connections from native host state (passwords are not persisted) // Sync RDP connections from native host state — decode base64 password if present
if (Array.isArray(state.rdpConnections)) { if (Array.isArray(state.rdpConnections)) {
// Merge: keep in-memory passwords for connections that already exist
rdpConnections = state.rdpConnections.map(c => { rdpConnections = state.rdpConnections.map(c => {
const existing = rdpConnections.find(e => e.id === c.id); const existing = rdpConnections.find(e => e.id === c.id);
return existing ? { ...c, password: existing.password || '' } : c; // Prefer in-memory password (user just typed it), then decode persisted base64
let password = (existing && existing.password) || '';
if (!password && c.passwordB64) {
try { password = decodeURIComponent(escape(atob(c.passwordB64))); } catch (_) {}
}
return { ...c, password };
}); });
renderRdpGrid(); renderRdpGrid();
} }