Answer prose round 1: 0 🔴, 2 🟡 (0 misread); the view header calls the link a URL, the always-present code loses its guard, the test comment goes
CI / full-gate (push) Successful in 3m31s

This commit is contained in:
2026-10-31 13:11:21 +01:00
parent f340933e39
commit 3592a30f98
2 changed files with 3 additions and 3 deletions
@@ -2,7 +2,7 @@
Admin user create/edit form body, captured into the shell content slot. Config:
form { action, csrfToken, submitLabel, cancelHref, fields: field.ejs config[] }
edit? { nextLabel, stateAction, recoveryAction, deleteAction } (edit mode only)
recovery? { code, link } shown after a recovery code is generated; link is the flow the code was minted on, the only one that accepts it
recovery? { code, link } shown after a recovery code is generated; link is the URL of the flow the code was minted on, the only flow that accepts the code
error? string shown when a write was rejected
%><%
const form = locals.form;
@@ -14,7 +14,7 @@
<%- include("partials/alert", { text: locals.error, tone: "neg" }) %>
<% } -%>
<% if (recovery) { -%>
<div class="alert alert-pos" role="status"><svg class="ico ico-sm" aria-hidden="true"><use href="#i-check-circle"/></svg><div class="alert-body"><strong><%= t("admin.users.recovery.title") %></strong><span><%= t("admin.users.recovery.body") %> <a href="<%= recovery.link %>"><%= t("admin.users.recovery.link") %></a></span><% if (recovery.code) { %><span class="recovery-code"><code><%= recovery.code %></code></span><% } %></div></div>
<div class="alert alert-pos" role="status"><svg class="ico ico-sm" aria-hidden="true"><use href="#i-check-circle"/></svg><div class="alert-body"><strong><%= t("admin.users.recovery.title") %></strong><span><%= t("admin.users.recovery.body") %> <a href="<%= recovery.link %>"><%= t("admin.users.recovery.link") %></a></span><span class="recovery-code"><code><%= recovery.code %></code></span></div></div>
<% } -%>
<form class="form-card" method="post" action="<%= localeHref(form.action) %>">
<input type="hidden" name="_csrf" value="<%= form.csrfToken %>">
+1 -1
View File
@@ -139,7 +139,7 @@ test("admin Users screen: gate, list/filter, create, edit, deactivate, delete, r
const recHtml = await rec.text();
assert.match(recHtml, /Recovery code generated/);
assert.match(recHtml, /<code>123456<\/code>/);
assert.match(recHtml, new RegExp(`<a href="http://kratos/self-service/recovery\\?flow=flow-${target.id}">`)); // the code only works in the flow that minted it
assert.match(recHtml, new RegExp(`<a href="http://kratos/self-service/recovery\\?flow=flow-${target.id}">`));
// Delete needs a deliberate confirm step (zero-JS): GET renders the interstitial, POST performs it.
const confirm = await (await get(`/admin/users/${target.id}/delete`)).text();