Dashboard: Matrix chat card — self-serve one extra federated MXID below API keys
This commit is contained in:
1 parent
98f829b65a
commit
92158da5ea
1 file changed
+71
+71
@@ -159,6 +159,30 @@ async def api_revoke_key(name: str, request: Request):
|
|||||||
return JSONResponse({"error": e.detail}, status_code=e.status_code)
|
return JSONResponse({"error": e.detail}, status_code=e.status_code)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/matrix-mxid")
|
||||||
|
async def api_get_matrix_mxid(request: Request):
|
||||||
|
identity = get_user_identity(request)
|
||||||
|
if not identity:
|
||||||
|
return JSONResponse({"error": "unauthenticated"}, status_code=401)
|
||||||
|
try:
|
||||||
|
return await broker_get(identity, "/broker/matrix-mxid")
|
||||||
|
except HTTPException as e:
|
||||||
|
return JSONResponse({"error": e.detail}, status_code=e.status_code)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/api/matrix-mxid")
|
||||||
|
async def api_set_matrix_mxid(request: Request):
|
||||||
|
identity = get_user_identity(request)
|
||||||
|
if not identity:
|
||||||
|
return JSONResponse({"error": "unauthenticated"}, status_code=401)
|
||||||
|
body = await request.json()
|
||||||
|
mxid = (body.get("matrix_mxid") or "").strip()
|
||||||
|
try:
|
||||||
|
return await broker_post(identity, "/broker/matrix-mxid", {"matrix_mxid": mxid})
|
||||||
|
except HTTPException as e:
|
||||||
|
return JSONResponse({"error": e.detail}, status_code=e.status_code)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# OIDC routes — authorization-code flow against Cloudron's OIDC provider.
|
# OIDC routes — authorization-code flow against Cloudron's OIDC provider.
|
||||||
# Active only when the `oidc` addon is configured (CLOUDRON_OIDC_* present).
|
# Active only when the `oidc` addon is configured (CLOUDRON_OIDC_* present).
|
||||||
@@ -532,6 +556,16 @@ PAGE_HTML = """<!DOCTYPE html>
|
|||||||
<button class="ghost" onclick="$('key-reveal').style.display='none';">Dismiss</button>
|
<button class="ghost" onclick="$('key-reveal').style.display='none';">Dismiss</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h2>Matrix chat</h2>
|
||||||
|
<p class="hint">You're invited to the co-op's Matrix space at your co-op account (<code id="local-mxid">@you:inference.coop</code>). Prefer to use an existing account on another server instead? Add it below (one account).</p>
|
||||||
|
<div class="new-key">
|
||||||
|
<input id="mxid-input" type="text" placeholder="e.g. @you:matrix.org" maxlength="255" />
|
||||||
|
<button class="primary" id="mxid-btn" onclick="saveMxid()">Save</button>
|
||||||
|
</div>
|
||||||
|
<div class="hint" id="mxid-status"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
@@ -594,11 +628,48 @@ async function load() {
|
|||||||
renderModels(d.models || []);
|
renderModels(d.models || []);
|
||||||
renderBoard(d.coop_models || []);
|
renderBoard(d.coop_models || []);
|
||||||
renderKeys(d.keys || []);
|
renderKeys(d.keys || []);
|
||||||
|
loadMxid();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
flash('Could not load usage: ' + e.message, false);
|
flash('Could not load usage: ' + e.message, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadMxid() {
|
||||||
|
try {
|
||||||
|
const r = await fetch('/api/matrix-mxid');
|
||||||
|
if (r.status === 401) return;
|
||||||
|
const d = await r.json();
|
||||||
|
if (d.error) return;
|
||||||
|
if (d.local_mxid) $('local-mxid').textContent = d.local_mxid;
|
||||||
|
if (d.matrix_mxid) {
|
||||||
|
$('mxid-input').value = d.matrix_mxid;
|
||||||
|
$('mxid-status').textContent = 'Using ' + d.matrix_mxid + ' for Matrix invites.';
|
||||||
|
}
|
||||||
|
} catch (e) { /* non-critical */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveMxid() {
|
||||||
|
const mxid = $('mxid-input').value.trim();
|
||||||
|
const btn = $('mxid-btn');
|
||||||
|
btn.disabled = true;
|
||||||
|
$('mxid-status').textContent = '';
|
||||||
|
try {
|
||||||
|
const r = await fetch('/api/matrix-mxid', {
|
||||||
|
method: 'POST', headers: {'Content-Type': 'application/json'},
|
||||||
|
body: JSON.stringify({ matrix_mxid: mxid })
|
||||||
|
});
|
||||||
|
const d = await r.json();
|
||||||
|
if (d.error) { $('mxid-status').textContent = d.error; }
|
||||||
|
else if (mxid) {
|
||||||
|
$('mxid-status').textContent = 'Saved — invitations will go to ' + mxid + '.';
|
||||||
|
} else {
|
||||||
|
$('mxid-status').textContent = 'Cleared — your co-op account will be used for Matrix.';
|
||||||
|
$('mxid-input').value = '';
|
||||||
|
}
|
||||||
|
} catch (e) { $('mxid-status').textContent = 'Could not save: ' + e.message; }
|
||||||
|
btn.disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
function renderModels(models) {
|
function renderModels(models) {
|
||||||
const el = $('models');
|
const el = $('models');
|
||||||
if (!models.length) { el.innerHTML = ''; return; }
|
if (!models.length) { el.innerHTML = ''; return; }
|
||||||
|
|||||||
Reference in new issue
Block a user