fix(setup): role-aware PAT scope+TTL in setupNewClaude JS (Task 4 spec fix)
This commit is contained in:
parent
f731ee7897
commit
7965f8021d
2 changed files with 46 additions and 4 deletions
|
|
@ -993,6 +993,11 @@
|
|||
|
||||
<script>
|
||||
(function() {
|
||||
// Role from the Jinja ctx — drives the PAT mint shape below
|
||||
// (analyst tile mints a 1h scope=bootstrap-analyst PAT, admin keeps
|
||||
// the historical 90-day general-purpose PAT).
|
||||
const ROLE = "{{ role }}";
|
||||
|
||||
function copyToClipboard(text) {
|
||||
if (navigator.clipboard && window.isSecureContext) {
|
||||
return navigator.clipboard.writeText(text);
|
||||
|
|
@ -1091,14 +1096,17 @@
|
|||
btn.disabled = true;
|
||||
btn.textContent = 'Generating token…';
|
||||
try {
|
||||
// Role-aware PAT mint: analyst tile gets a 1h
|
||||
// scope=bootstrap-analyst PAT (server clamps ttl ≤ 3600);
|
||||
// admin tile keeps the historical 90-day general PAT.
|
||||
var tokenBody = ROLE === "analyst"
|
||||
? { name: defaultTokenName(), scope: "bootstrap-analyst", ttl_seconds: 3600 }
|
||||
: { name: defaultTokenName(), expires_in_days: 90 };
|
||||
var resp = await fetch('/auth/tokens', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
name: defaultTokenName(),
|
||||
expires_in_days: 90,
|
||||
}),
|
||||
body: JSON.stringify(tokenBody),
|
||||
});
|
||||
if (resp.status === 401) {
|
||||
window.location.href = '/login?next=' + encodeURIComponent(window.location.pathname);
|
||||
|
|
|
|||
|
|
@ -73,3 +73,37 @@ def test_setup_page_invalid_role_falls_back(client):
|
|||
"""
|
||||
resp = client.get("/setup?role=hacker", follow_redirects=True)
|
||||
assert resp.status_code in (200, 422)
|
||||
|
||||
|
||||
def test_setup_page_analyst_js_uses_bootstrap_scope(client):
|
||||
"""Analyst tile's setupNewClaude JS must mint bootstrap-analyst PATs.
|
||||
|
||||
The JS PAT mint must be role-aware: analyst gets a short-TTL
|
||||
bootstrap-analyst-scoped PAT (server clamps ttl ≤ 3600s), not the
|
||||
historical 90-day general PAT. Asserts the wiring at the rendered
|
||||
template level so we catch any regression in either the Jinja ctx
|
||||
plumbing or the JS branching.
|
||||
"""
|
||||
resp = client.get("/setup?role=analyst", follow_redirects=True)
|
||||
assert resp.status_code == 200
|
||||
text = resp.text
|
||||
# The role variable must be set to analyst in JS scope.
|
||||
assert (
|
||||
'const ROLE = "analyst"' in text
|
||||
or 'ROLE = "analyst"' in text
|
||||
or 'data-role="analyst"' in text
|
||||
)
|
||||
# The bootstrap-analyst scope must appear in the JS PAT-mint body.
|
||||
assert "bootstrap-analyst" in text
|
||||
assert "ttl_seconds" in text
|
||||
|
||||
|
||||
def test_setup_page_admin_js_uses_general_scope(client):
|
||||
"""Admin tile's setupNewClaude JS must keep the existing 90-day
|
||||
expires_in_days behavior — byte-identical PAT mint shape so existing
|
||||
admin flows don't regress.
|
||||
"""
|
||||
resp = client.get("/setup?role=admin", follow_redirects=True)
|
||||
assert resp.status_code == 200
|
||||
text = resp.text
|
||||
assert "expires_in_days" in text # still present in the admin body
|
||||
|
|
|
|||
Loading…
Reference in a new issue