87 lines
3 KiB
Common Lisp
87 lines
3 KiB
Common Lisp
|
(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(() => {
|
||
|
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 %}")
|