Users can now generate a random disposable alias by selecting an allowed domain from a dropdown and clicking "Generate alias", without specifying a custom local part. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
132 lines
4.8 KiB
HTML
132 lines
4.8 KiB
HTML
{{template "header" .}}
|
|
<h1 class="page-title">Welcome, {{.login}}</h1>
|
|
|
|
<nav class="tabs">
|
|
<button class="tab-btn active" onclick="showTab(this,'account')">Account</button>
|
|
{{if or .emails .aliases .alias_domains}}<button class="tab-btn" onclick="showTab(this,'email')">Email & Aliases</button>{{end}}
|
|
<button class="tab-btn" onclick="showTab(this,'api')">API</button>
|
|
</nav>
|
|
|
|
<div id="tab-account" class="tab-panel">
|
|
{{if .fields}}
|
|
<table class="info-table">
|
|
{{range .fields}}
|
|
<tr>
|
|
<th>{{.Label}}</th>
|
|
<td>{{.Value}}</td>
|
|
</tr>
|
|
{{end}}
|
|
</table>
|
|
{{else}}
|
|
<p class="section-empty">No account information available.</p>
|
|
{{end}}
|
|
</div>
|
|
|
|
{{if or .emails .aliases .alias_domains}}
|
|
<div id="tab-email" class="tab-panel hidden">
|
|
{{if .emails}}
|
|
<h3 class="section-title">Email addresses</h3>
|
|
<ul class="email-list">
|
|
{{range .emails}}
|
|
<li>{{.}}</li>
|
|
{{end}}
|
|
</ul>
|
|
{{end}}
|
|
{{if .aliases}}
|
|
<h3 class="section-title">Disposable aliases</h3>
|
|
<ul class="alias-list">
|
|
{{range .aliases}}
|
|
<li id="{{.ElemID}}" class="alias-item">
|
|
<span class="alias-value">{{.Value}}</span>
|
|
<button class="btn btn-danger btn-sm"
|
|
data-alias="{{.URLSafe}}"
|
|
data-token="{{.Token}}"
|
|
data-elem="{{.ElemID}}"
|
|
onclick="deleteAlias(this)">Delete</button>
|
|
</li>
|
|
{{end}}
|
|
</ul>
|
|
{{end}}
|
|
{{if .alias_domains}}
|
|
<div class="alias-create">
|
|
<select id="alias-domain" class="alias-domain-select">
|
|
{{range .alias_domains}}
|
|
<option value="{{.}}">@{{.}}</option>
|
|
{{end}}
|
|
</select>
|
|
<button class="btn btn-primary btn-sm"
|
|
data-token="{{.api_token}}"
|
|
onclick="createAlias(this)">Generate alias</button>
|
|
<span id="alias-create-error" class="alias-create-error"></span>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
|
|
<div id="tab-api" class="tab-panel hidden">
|
|
<p class="section-desc">Use this token to authenticate with the Addy.io-compatible alias API:</p>
|
|
<div class="api-token-box">{{.api_token}}</div>
|
|
<p class="section-desc">Endpoint: <code>POST /api/v1/aliases</code> — <code>DELETE /api/v1/aliases/{alias}</code></p>
|
|
<p class="section-desc">Set the <code>Authorization: Bearer <token></code> header on each request.</p>
|
|
</div>
|
|
|
|
<script>
|
|
function showTab(btn, name) {
|
|
document.querySelectorAll('.tab-panel').forEach(function(p) { p.classList.add('hidden'); });
|
|
document.querySelectorAll('.tab-btn').forEach(function(b) { b.classList.remove('active'); });
|
|
document.getElementById('tab-' + name).classList.remove('hidden');
|
|
btn.classList.add('active');
|
|
}
|
|
function deleteAlias(btn) {
|
|
fetch('/api/v1/aliases/' + btn.dataset.alias, {
|
|
method: 'DELETE',
|
|
headers: {'Authorization': 'Bearer ' + btn.dataset.token}
|
|
}).then(function(r) {
|
|
if (r.ok) document.getElementById(btn.dataset.elem).remove();
|
|
});
|
|
}
|
|
function createAlias(btn) {
|
|
var domain = document.getElementById('alias-domain').value;
|
|
var errEl = document.getElementById('alias-create-error');
|
|
errEl.textContent = '';
|
|
btn.disabled = true;
|
|
fetch('/api/v1/aliases', {
|
|
method: 'POST',
|
|
headers: {'Authorization': 'Bearer ' + btn.dataset.token, 'Content-Type': 'application/json'},
|
|
body: JSON.stringify({domain: domain})
|
|
}).then(function(r) {
|
|
btn.disabled = false;
|
|
if (!r.ok) { return r.text().then(function(t) { errEl.textContent = t; }); }
|
|
return r.json().then(function(data) {
|
|
var list = document.querySelector('.alias-list');
|
|
if (!list) {
|
|
var h = document.createElement('h3');
|
|
h.className = 'section-title';
|
|
h.textContent = 'Disposable aliases';
|
|
document.querySelector('.alias-create').before(h);
|
|
list = document.createElement('ul');
|
|
list.className = 'alias-list';
|
|
document.querySelector('.alias-create').before(list);
|
|
}
|
|
var idx = list.children.length;
|
|
var li = document.createElement('li');
|
|
li.id = 'alias-' + idx;
|
|
li.className = 'alias-item';
|
|
var span = document.createElement('span');
|
|
span.className = 'alias-value';
|
|
span.textContent = data.data.email;
|
|
var del = document.createElement('button');
|
|
del.className = 'btn btn-danger btn-sm';
|
|
del.dataset.alias = encodeURIComponent(data.data.email);
|
|
del.dataset.token = btn.dataset.token;
|
|
del.dataset.elem = li.id;
|
|
del.textContent = 'Delete';
|
|
del.onclick = function() { deleteAlias(del); };
|
|
li.appendChild(span);
|
|
li.appendChild(del);
|
|
list.appendChild(li);
|
|
});
|
|
});
|
|
}
|
|
</script>
|
|
{{template "footer" .}}
|