Skip to main content

tuwunel_api/oidc/device/
consent.rs

1use const_str::format as const_format;
2use ruma::UserId;
3use tuwunel_core::utils::html::escape as html_escape;
4use tuwunel_service::oauth::server::format_user_code;
5
6use super::DEVICE_HEAD;
7
8pub(super) fn consent_html(
9	user_id: &UserId,
10	client_label: &str,
11	user_code: &str,
12	scope: &str,
13	login_token: &str,
14) -> String {
15	// Token first, free-form client last: a later replace fills a placeholder left
16	// in a request value.
17	PAGE_HTML
18		.replace("{token}", &html_escape(login_token))
19		.replace("{code_value}", &html_escape(user_code))
20		.replace("{code_display}", &html_escape(&format_user_code(user_code)))
21		.replace("{user}", &html_escape(user_id.as_str()))
22		.replace("{scope}", &html_escape(scope))
23		.replace("{client}", &html_escape(client_label))
24}
25
26static PAGE_HTML: &str = const_format!(
27	r#"
28<!DOCTYPE html>
29<html lang="en">
30	<head>
31		{DEVICE_HEAD}
32		<title>Authorize device</title>
33	</head>
34	<body>
35		<h1>Authorize device</h1>
36		<p>A device is requesting to sign in as <strong>{{user}}</strong>.</p>
37		<p>Application: <strong>{{client}}</strong></p>
38		<p>Code: <code>{{code_display}}</code></p>
39		<p>Requested access: <code>{{scope}}</code></p>
40		<form method="POST" action="/_tuwunel/oidc/device_callback">
41			<input type="hidden" name="user_code" value="{{code_value}}">
42			<input type="hidden" name="loginToken" value="{{token}}">
43			<button type="submit" name="action" value="approve" class="primary">
44				Approve
45			</button>
46			<button type="submit" name="action" value="deny" class="danger">
47				Deny
48			</button>
49		</form>
50	</body>
51</html>"#
52);