(text "{% extends \"root.html\" %} {% block head %}")
(title
(text "{{ app.title }} - {{ config.name }}"))
(text "{% endblock %} {% block body %} {{ macros::nav() }}")
(main
("class" "flex flex-col gap-2")
(div
("class" "w-full flex flex-col gap-2")
(div
("class" "card-nest")
(div
("class" "card flex flex-col gap-2")
(h4 (text "Would you like to allow \"{{ app.title }}\" to access your account?"))
(p (text "This app is requesting the following permissions on your account:"))
(div
("class" "card")
(ul
(text "{% for scope in app.scopes -%}")
(li
(a
("href" "https://tetratto.com/reference/tetratto/model/oauth/enum.AppScope.html#variant.{{ scope }}")
("target" "_blank")
(text "{{ scope }}")))
(text "{%- endfor %}")))
(p (text "You can revoke this app's permissions at any time through your connection settings.")))
(div
("class" "card flex gap-2")
(button
("onclick" "authorize()")
(str (text "developer:action.authorize")))
(a
("class" "button secondary")
("href" "javascript:window.close()")
(str (text "dialog:action.cancel")))))))
(script
(text "setTimeout(() => {
// {% if app.redirect|length == 0 %}
alert(\"App has an invalid redirect. Please contact the owner for help.\");
window.close();
return;
// {% endif %}
// ...
globalThis.authorize = async (event) => {
if (
!(await trigger(\"atto::confirm\", [
\"Are you sure you would like to do this?\",
]))
) {
return;
}
const verifier = await trigger(\"connections::pkce_verifier\", [
128,
]);
const challenge = await trigger(\"connections::pkce_challenge\", [
verifier,
]);
fetch(\"/api/v1/apps/{{ app.id }}/grant\", {
method: \"POST\",
headers: {
\"Content-Type\": \"application/json\",
},
body: JSON.stringify({
challenge
})
})
.then((res) => res.json())
.then((res) => {
trigger(\"atto::toast\", [
res.ok ? \"success\" : \"error\",
res.message,
]);
if (res.ok) {
const search = new URLSearchParams(window.location.search);
search.append(\"verifier\", verifier);
search.append(\"token\", res.payload);
window.location.href = `{{ app.redirect|remove_script_tags|safe }}?${search.toString()}`;
}
});
};
}, 250);"))
(text "{% endblock %}")