mirror of
https://github.com/coder/coder.git
synced 2026-06-03 04:58:23 +00:00
a8e7f329ac
Currently when a user clicks either the Cancel or Allow button on the authorization page the client app URI is executed but the page does not land to the main dashboard page, leaving the two buttons open for multiple clicks from the user. Aside from the potential problems it might cause by activating the callback URI multiple times, the page also provides poor UX because users usually expect the authorization tab to return to the dashboard. The consent page now executes the OAuth2 callback (auth code on Allow, `access_denied` on Cancel) and hides the two buttons and updates the existing description with a user instruction to close the window. Initial implementation relied on a pop-up window executing the callback while the main window was redirected to the dashboard main page. - resolves https://github.com/coder/coder/issues/20323 <!-- If you have used AI to produce some or all of this PR, please ensure you have read our [AI Contribution guidelines](https://coder.com/docs/about/contributing/AI_CONTRIBUTING) before submitting. -->
166 lines
4.2 KiB
HTML
166 lines
4.2 KiB
HTML
{{/* This template is used by application handlers to render allowing oauth2
|
|
links */}}
|
|
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>Application {{.AppName}}</title>
|
|
<style>
|
|
* {
|
|
padding: 0;
|
|
margin: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
html,
|
|
body {
|
|
background-color: #05060b;
|
|
color: #f7f9fd;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-family: sans-serif;
|
|
font-size: 16px;
|
|
height: 100%;
|
|
}
|
|
|
|
.container {
|
|
--side-padding: 24px;
|
|
width: 100%;
|
|
max-width: calc(320px + var(--side-padding) * 2);
|
|
padding: 0 var(--side-padding);
|
|
text-align: center;
|
|
}
|
|
|
|
.icons-container {
|
|
align-items: center;
|
|
display: flex;
|
|
justify-content: center;
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.coder-svg,
|
|
.app-icon {
|
|
width: 80px;
|
|
}
|
|
|
|
.connect-symbol {
|
|
font-size: 40px;
|
|
font-weight: bold;
|
|
margin: 0 10px;
|
|
}
|
|
|
|
h1 {
|
|
font-weight: 700;
|
|
font-size: 36px;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
p,
|
|
li {
|
|
color: #b2bfd7;
|
|
line-height: 140%;
|
|
}
|
|
|
|
.user-name {
|
|
font-weight: bold;
|
|
}
|
|
|
|
.button-group {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 12px;
|
|
margin-top: 24px;
|
|
}
|
|
|
|
.button-group a,
|
|
.button-group button {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 6px 16px;
|
|
border-radius: 4px;
|
|
border: 1px solid #2c3854;
|
|
text-decoration: none;
|
|
background: none;
|
|
font-size: inherit;
|
|
color: inherit;
|
|
width: 200px;
|
|
height: 42px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.button-group a:hover,
|
|
.button-group button:hover {
|
|
border-color: hsl(222, 31%, 40%);
|
|
}
|
|
|
|
.button-group .primary-button {
|
|
background-color: #2c3854;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="icons-container">
|
|
{{- if .AppIcon }}
|
|
<img class="app-icon" src="{{ .AppIcon }}" />
|
|
<div class="connect-symbol">+</div>
|
|
{{end}}
|
|
<img class="coder-svg" src="/icon/coder.svg" alt="Coder" />
|
|
</div>
|
|
<h1>Authorize {{ .AppName }}</h1>
|
|
<p id="description">
|
|
Allow {{ .AppName }} to have full access to your
|
|
<span class="user-name">{{ .Username }}</span> account?
|
|
</p>
|
|
<div class="button-group" id="button-group">
|
|
<form id="allow-form" method="POST" style="display: inline;">
|
|
<input type="hidden" name="csrf_token" value="{{ .CSRFToken }}" />
|
|
<button type="submit" class="primary-button">Allow</button>
|
|
</form>
|
|
<a id="cancel-link" href="{{ .CancelURI }}">Cancel</a>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
(function () {
|
|
var appName = "{{ .AppName }}";
|
|
var description = document.getElementById("description");
|
|
var buttonGroup = document.getElementById("button-group");
|
|
var allowForm = document.getElementById("allow-form");
|
|
var cancelLink = document.getElementById("cancel-link");
|
|
|
|
function showFeedback(message) {
|
|
buttonGroup.style.display = "none";
|
|
description.textContent = message;
|
|
}
|
|
|
|
allowForm.addEventListener("submit", function (e) {
|
|
e.preventDefault();
|
|
showFeedback(
|
|
appName +
|
|
" is now authorized to access your account. This window can now be closed."
|
|
);
|
|
setTimeout(function () {
|
|
allowForm.submit();
|
|
}, 500);
|
|
});
|
|
|
|
cancelLink.addEventListener("click", function (e) {
|
|
e.preventDefault();
|
|
showFeedback(
|
|
appName +
|
|
" was denied access to your account. This window can now be closed."
|
|
);
|
|
setTimeout(function () {
|
|
window.location.href = cancelLink.href;
|
|
}, 500);
|
|
});
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|