Files
sso-manager-node/nodejs/views/login.ejs
T
wmantly 8ed4505dc0 Explain why the user landed on the login page
Landing here with ?redirect= and no explanation is exactly what happens
when another app's "Log in with SSO" sends an unauthenticated user
through /oauth/authorize, which bounces them here. Shows a contextual
banner: a specific message when the redirect target is an OAuth
authorize URL, a generic "you'll be sent back" message otherwise.

Verified live for both cases (OAuth-authorize redirect and a plain
redirect) against a local stack.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-28 13:09:53 -04:00

186 lines
6.8 KiB
Plaintext
Executable File

<%- include('top') %>
<script type="text/javascript">
app.auth.isLoggedIn(function(error, isLoggedIn){
if(isLoggedIn){
app.auth.logInRedirect();
}
});
// Landing here with no explanation ("why am I on the SSO login page?") is
// exactly what happens when another app's "Log in with SSO" button sends
// an unauthenticated user through /oauth/authorize, which bounces them
// here with ?redirect=. Tell them what's happening instead of leaving it
// a mystery.
$(document).ready(function(){
var redirect = <%- JSON.stringify(redirect || '') %>;
if(redirect){
var isOauth = /\/oauth\/authorize/.test(redirect);
var message = isOauth
? 'Log in to continue — an application is requesting access to your account.'
: "Log in to continue to what you were doing — you'll be sent back afterward.";
app.messages.action(message, $('.card').first(), 'info');
}
});
function setOtpMethod(method) {
$('#otpMethodInput').val(method);
$('#otpMethodEmail').toggleClass('active', method === 'email').toggleClass('btn-secondary', method === 'email').toggleClass('btn-outline-secondary', method !== 'email');
$('#otpMethodSms').toggleClass('active', method === 'sms').toggleClass('btn-secondary', method === 'sms').toggleClass('btn-outline-secondary', method !== 'sms');
}
function resetOtpForm() {
$('#otpStep2').hide();
$('#otpStep1').show().find('input[name=login]').val('');
setOtpMethod('email');
}
</script>
<div class="row">
<div class="col-md-1">
</div>
<div class="col-md-3">
<div class="shadow-lg card">
<div class="card-header shadow">
Password Log in
</div>
<div class="card-header shadow actionMessage" style="display:none">
</div>
<div class="card-body">
<form action="auth/login" onsubmit="formAJAX(this)" evalAJAX="
app.auth.setToken(data.token);
app.auth.logInRedirect();
">
<input type="hidden" name="redirect" value="<%= redirect %>">
<div class="mb-3">
<label></label>
<div class="input-group">
<span class="input-group-text" id="addon-wrapping"><i class="fa-solid fa-user-tie"></i></span>
<input type="text" name="username" class="form-control" placeholder="jsmith" aria-label="Username" aria-describedby="addon-wrapping">
</div>
</div>
<div class="mb-3">
<div class="input-group">
<span class="input-group-text" id="addon-wrapping"><i class="fa-solid fa-key"></i></span>
<input type="password" name="password" class="form-control" placeholder="huunteR!23" aria-label="Username" aria-describedby="addon-wrapping">
</div>
</div>
<button type="submit" class="btn btn-outline-dark"><i class="fad fa-sign-in"></i> Log in</button>
</form>
</div>
</div>
</div>
<!-- <div class="col-md-3">
<div class="shadow-lg card border-danger">
<div class="card-header shadow">
Social Login
</div>
<div class="card-header shadow actionMessage" style="display:none">
</div>
<div class="card-body">
<h3>Coming soon!</h3>
<p>
<ul class="list-group">
<li class="list-group-item"><i class="fab fa-google"></i> Login with google OATH</li>
<li class="list-group-item"><i class="fab fa-github"></i> Login with github OATH</li>
<li class="list-group-item"><i class="fab fa-facebook"></i> Login with facebook OATH</li>
</ul>
</p>
</div>
</div>
</div>-->
<div class="col-md-3">
<div class="shadow-lg card">
<div class="card-header shadow">
<i class="fa-solid fa-mobile-screen"></i>
Login with a Code
</div>
<div class="card-header shadow actionMessage" style="display:none"></div>
<div class="card-body">
<form id="otpStep1" action="auth/otp/request" onsubmit="formAJAX(this)" evalAJAX="
$('#otpVerifyLogin').val(formData.login);
$('#otpSentMsg').text('Code sent via ' + data.method + '. Expires at ' + new Date(data.expires_at).toLocaleTimeString() + '.');
$('#otpStep1').hide();
$('#otpStep2').show();
setTimeout(function(){ $('#otpCode').focus(); }, 100);
">
<input type="hidden" name="method" id="otpMethodInput" value="email">
<div class="mb-3">
<div class="input-group">
<span class="input-group-text"><i class="fa-solid fa-user-tie"></i></span>
<input type="text" name="login" class="form-control" placeholder="username or email">
</div>
</div>
<div class="mb-3">
<div class="btn-group w-100" role="group">
<button type="button" id="otpMethodEmail" class="btn btn-secondary active" onclick="setOtpMethod('email')">
<i class="fa-solid fa-envelope"></i> Email
</button>
<button type="button" id="otpMethodSms" class="btn btn-outline-secondary" onclick="setOtpMethod('sms')">
<i class="fa-solid fa-mobile-screen"></i> SMS
</button>
</div>
</div>
<button type="submit" class="btn btn-outline-dark">
<i class="fa-solid fa-paper-plane"></i> Send Code
</button>
</form>
<form id="otpStep2" action="auth/otp/verify" onsubmit="formAJAX(this)" style="display:none" evalAJAX="
app.auth.setToken(data.token);
app.auth.logInRedirect();
">
<input type="hidden" name="login" id="otpVerifyLogin">
<p class="text-muted small mb-3" id="otpSentMsg"></p>
<div class="mb-3">
<div class="input-group">
<span class="input-group-text"><i class="fa-solid fa-hashtag"></i></span>
<input type="text" name="code" id="otpCode" class="form-control" placeholder="123456" maxlength="6" inputmode="numeric" autocomplete="one-time-code">
</div>
</div>
<button type="submit" class="btn btn-outline-dark me-2">
<i class="fa-solid fa-check"></i> Verify
</button>
<button type="button" class="btn btn-link btn-sm text-muted" onclick="resetOtpForm()">Start over</button>
</form>
</div>
</div>
</div>
<div class="col-md-3">
<div class="shadow-lg card">
<div class="card-header shadow">
Password Reset
</div>
<div class="card-header shadow actionMessage" style="display:none">
</div>
<div class="card-body">
<p>
Forgot your password? Or your user name? No problem! Just
enter you email address below and if you are in our system,
we will email with the required information to get back up
and running!
</p>
<form action="auth/resetpassword" onsubmit="formAJAX(this)">
<input type="hidden" name="redirect" value="<%= redirect %>">
<div class="mb-3">
<label></label>
<div class="input-group">
<span class="input-group-text" id="addon-wrapping"><i class="fa-solid fa-at"></i></span>
<input type="text" name="mail" class="form-control" placeholder="john.smith@mail.com" aria-label="Email" aria-describedby="addon-wrapping">
</div>
</div>
<button type="submit" class="btn btn-outline-dark"><i class="fad fa-question"></i> Help me!</button>
</form>
</div>
</div>
</div>
</div>
<%- include('bottom') %>