Files
cloudron-box/src/oidc_templates/login.ejs
T

146 lines
4.8 KiB
Plaintext
Raw Normal View History

2023-03-13 16:46:18 +01:00
<!DOCTYPE html>
2023-03-11 17:22:27 +01:00
<html>
<head>
2023-03-13 16:46:18 +01:00
<meta charset="utf-8" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height" />
2023-03-23 10:00:17 +01:00
<title>Login to <%= name %></title>
2023-03-13 16:46:18 +01:00
2023-05-11 12:15:10 +02:00
<link id="favicon" type="image/png" rel="icon" href="/api/v1/cloudron/avatar">
<link rel="apple-touch-icon" href="/api/v1/cloudron/avatar">
<link rel="icon" href="/api/v1/cloudron/avatar">
2023-03-13 16:46:18 +01:00
<!-- Theme CSS -->
<link type="text/css" rel="stylesheet" href="/theme.css">
<!-- Fontawesome -->
<link type="text/css" rel="stylesheet" href="/3rdparty/fontawesome/css/all.css"/>
<!-- Bootstrap Core JavaScript -->
2023-03-13 19:08:41 +01:00
<script type="text/javascript" src="/3rdparty/js/jquery.min.js"></script>
2023-03-13 16:46:18 +01:00
<script type="text/javascript" src="/3rdparty/js/bootstrap.min.js"></script>
2023-03-11 17:22:27 +01:00
2023-05-12 18:47:48 +02:00
<script type="text/javascript" src="/3rdparty/js/password-reveal.js"></script>
2023-04-27 16:20:32 +02:00
<style>
.card {
padding: 20px;
margin-bottom: 0;
max-width: 620px;
min-height: 100%;
}
.avatar {
margin-top: 20px;
}
@media(min-width:620px) {
.card {
margin-bottom: 15px;
margin-top: 100px;
min-height: auto;
}
.avatar {
margin-top: -84px
}
}
</style>
2023-03-11 17:22:27 +01:00
</head>
<body>
2023-03-13 16:46:18 +01:00
<div class="layout-root">
<div class="layout-content">
2023-04-27 16:20:32 +02:00
<div class="card">
2023-03-13 16:46:18 +01:00
<div class="row">
<div class="col-md-12" style="text-align: center;">
2023-05-12 13:32:43 +02:00
<img width="128" height="128" class="avatar" src="<%= iconUrl %>"/>
2023-03-13 16:46:18 +01:00
<br/>
2023-05-12 13:32:43 +02:00
<h1><small>Login to</small> <%= name %></h1>
2023-03-11 17:22:27 +01:00
</div>
2023-03-13 16:46:18 +01:00
</div>
<br/>
<div class="row">
<div class="col-md-12">
2023-03-13 19:08:41 +01:00
<form id="loginForm">
2023-03-13 16:46:18 +01:00
<div class="form-group">
<label class="control-label" for="inputUsername">Username</label>
<input type="text" class="form-control" id="inputUsername" name="username" autofocus required>
</div>
<div class="form-group">
<label class="control-label" for="inputPassword">Password</label>
<input type="password" class="form-control" name="password" id="inputPassword" required password-reveal>
2023-05-12 14:31:26 +02:00
<p class="has-error" id="passwordError"></p>
2023-03-13 16:46:18 +01:00
</div>
<div class="form-group">
<label class="control-label" for="inputTotpToken">2FA Token (if enabled)</label>
2023-03-13 16:46:18 +01:00
<input type="text" class="form-control" name="totpToken" id="inputTotpToken" value="">
2023-05-12 14:31:26 +02:00
<p class="has-error" id="totpError"></p>
2023-03-13 16:46:18 +01:00
</div>
2023-05-22 20:32:33 +02:00
<a href="/login.html?passwordReset=1">Reset password</a>
2023-03-13 16:46:18 +01:00
<button class="btn btn-primary btn-outline pull-right" type="submit">Log in</button>
</form>
2023-03-11 17:22:27 +01:00
</div>
2023-03-13 16:46:18 +01:00
</div>
</div>
</div>
</div>
<script>
2023-03-13 19:08:41 +01:00
document.getElementById('loginForm').addEventListener('submit', function (event) {
event.preventDefault();
2023-05-12 14:31:26 +02:00
document.getElementById('passwordError').innerText = '';
document.getElementById('totpError').innerText = '';
2023-03-13 19:08:41 +01:00
var apiUrl = '<%= submitUrl %>';
console.log('submit', apiUrl);
var body = {
username: document.getElementById('inputUsername').value,
password: document.getElementById('inputPassword').value,
totpToken: document.getElementById('inputTotpToken').value
};
2023-05-12 14:31:26 +02:00
let res;
2023-03-13 19:08:41 +01:00
fetch(apiUrl, {
method: 'POST',
2023-03-13 19:08:41 +01:00
body: JSON.stringify(body),
headers: { 'Content-type': 'application/json; charset=UTF-8' }
}).then(function (response) {
2023-05-12 14:31:26 +02:00
res = response;
return res.json(); // we always return objects
2023-03-13 19:08:41 +01:00
}).then(function (data) {
2023-05-12 14:31:26 +02:00
if (res.status === 401) {
if (data.message === 'Username and password does not match') {
document.getElementById('inputPassword').value = '';
document.getElementById('inputPassword').focus();
document.getElementById('passwordError').innerText = 'Invalid username or password';
} else if (data.message.indexOf('totpToken') !== -1) {
document.getElementById('inputTotpToken').value = '';
document.getElementById('inputTotpToken').focus();
document.getElementById('totpError').innerText = 'Missing or invalid 2FA Token';
} else {
throw new Error('Something went wrong');
}
} else if (res.status !== 200) {
throw new Error('Something went wrong');
}
if (data.redirectTo) window.location.href = data.redirectTo;
else console.log('login success but missing redirectTo in data:', data);
2023-03-13 19:08:41 +01:00
}).catch(function (error) {
2023-05-12 14:31:26 +02:00
document.getElementById('passwordError').innerText = 'Unexpected error. Try again later.';
console.warn(error, res);
2023-03-13 19:08:41 +01:00
});
});
2023-03-13 16:46:18 +01:00
</script>
2023-03-11 17:22:27 +01:00
</body>
</html>