diff --git a/internal/googleauth/templates/accounts.html b/internal/googleauth/templates/accounts.html
index 405713c2..6f16b275 100644
--- a/internal/googleauth/templates/accounts.html
+++ b/internal/googleauth/templates/accounts.html
@@ -816,50 +816,113 @@
Use from terminal
emptyState.classList.add('hidden');
accountBadge.textContent = accounts.length + ' account' + (accounts.length !== 1 ? 's' : '');
- accountsList.innerHTML = accounts.map((acc, index) => {
+ // Helper function to escape HTML and prevent XSS
+ function escapeHtml(text) {
+ const div = document.createElement('div');
+ div.textContent = text;
+ return div.innerHTML;
+ }
+
+ accountsList.innerHTML = '';
+ accounts.forEach((acc, index) => {
const initial = acc.email.charAt(0).toUpperCase();
const isDefault = acc.isDefault;
const services = acc.services || ['calendar', 'gmail', 'drive'];
- return `
-
-
- ${initial}
-
-
-
${acc.email}
-
- ${services.map(s => `${s}`).join('')}
-
-
-
-
- ${isDefault ? `
-
-
- Default
-
- ` : `
-
- `}
-
-
-
+ // Create account card element
+ const accountCard = document.createElement('div');
+ accountCard.className = 'account-card' + (isDefault ? ' default' : '');
+ accountCard.setAttribute('data-email', acc.email);
+ accountCard.onclick = (event) => upgradePermissions(acc.email, event);
+
+ // Create avatar
+ const avatar = document.createElement('div');
+ avatar.className = 'account-avatar';
+ avatar.style.background = getAvatarGradient(acc.email);
+ avatar.textContent = initial;
+
+ // Create account details
+ const details = document.createElement('div');
+ details.className = 'account-details';
+
+ const emailDiv = document.createElement('div');
+ emailDiv.className = 'account-email';
+ emailDiv.textContent = acc.email; // Use textContent to prevent XSS
+
+ const servicesDiv = document.createElement('div');
+ servicesDiv.className = 'account-services';
+ services.forEach(s => {
+ const tag = document.createElement('span');
+ tag.className = 'service-tag ' + s.toLowerCase();
+ tag.textContent = s;
+ servicesDiv.appendChild(tag);
+ });
+
+ details.appendChild(emailDiv);
+ details.appendChild(servicesDiv);
+
+ // Create actions section
+ const actions = document.createElement('div');
+ actions.className = 'account-actions';
+
+ // Upgrade button
+ const upgradeBtn = document.createElement('button');
+ upgradeBtn.className = 'upgrade-btn';
+ upgradeBtn.title = 'Add more permissions';
+ upgradeBtn.onclick = (event) => upgradePermissions(acc.email, event);
+ upgradeBtn.innerHTML = `
+
+ Permissions
+ `;
+ actions.appendChild(upgradeBtn);
+
+ // Default badge or set default button
+ if (isDefault) {
+ const defaultBadge = document.createElement('span');
+ defaultBadge.className = 'default-badge';
+ defaultBadge.innerHTML = `
+
+ Default
+ `;
+ actions.appendChild(defaultBadge);
+ } else {
+ const setDefaultBtn = document.createElement('button');
+ setDefaultBtn.className = 'set-default-btn';
+ setDefaultBtn.textContent = 'Set default';
+ setDefaultBtn.onclick = (event) => {
+ event.stopPropagation();
+ setDefault(acc.email);
+ };
+ actions.appendChild(setDefaultBtn);
+ }
+
+ // Remove button
+ const removeBtn = document.createElement('button');
+ removeBtn.className = 'remove-btn';
+ removeBtn.title = 'Remove account';
+ removeBtn.onclick = (event) => {
+ event.stopPropagation();
+ removeAccount(acc.email);
+ };
+ removeBtn.innerHTML = `
+
`;
- }).join('');
+ actions.appendChild(removeBtn);
+
+ // Assemble the card
+ accountCard.appendChild(avatar);
+ accountCard.appendChild(details);
+ accountCard.appendChild(actions);
+ accountsList.appendChild(accountCard);
+ });
}
}