feat: 🎸 Add SSO login button

This commit is contained in:
Jin 2025-03-26 01:48:42 +01:00
parent a30695b9fb
commit 886e63f128
5 changed files with 83 additions and 47 deletions

7
images/google-logo.svg Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
<path d="M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.716v2.259h2.908c1.702-1.567 2.684-3.875 2.684-6.615z" fill="#4285f4"/>
<path d="M9 18c2.43 0 4.467-.806 5.956-2.184l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332C2.438 15.983 5.482 18 9 18z" fill="#34a853"/>
<path d="M3.964 10.71c-.18-.54-.282-1.117-.282-1.71s.102-1.17.282-1.71V4.958H.957C.347 6.173 0 7.548 0 9s.348 2.827.957 4.042l3.007-2.332z" fill="#fbbc05"/>
<path d="M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0 5.482 0 2.438 2.017.957 4.958L3.964 7.29C4.672 5.163 6.656 3.58 9 3.58z" fill="#ea4335"/>
</svg>

After

Width:  |  Height:  |  Size: 805 B

View File

@ -32,6 +32,31 @@
color: var(--dropdown-item-icon-destructive-color) !important; color: var(--dropdown-item-icon-destructive-color) !important;
} }
.google-login-btn {
display: flex;
align-items: center;
justify-content: center;
background-color: #fff;
color: #757575;
border: 1px solid #ddd;
border-radius: 4px;
padding: 10px 20px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
margin-bottom: 20px;
text-decoration: none;
transition: background-color 0.3s;
}
.google-login-btn:hover {
background-color: #f5f5f5;
}
.google-login-btn img {
margin-right: 10px;
width: 18px;
height: 18px;
}
/* /*
* SEARCH PAGE * SEARCH PAGE
*/ */

View File

@ -14,18 +14,14 @@ import totp from '../services/totp.js';
import open_id from '../services/open_id.js'; import open_id from '../services/open_id.js';
function loginPage(req: Request, res: Response) { function loginPage(req: Request, res: Response) {
if (open_id.isOpenIDEnabled()) { res.render('login', {
res.redirect('/authenticate'); wrongPassword: false,
} else { wrongTotp: false,
res.render('login', { totpEnabled: totp.isTotpEnabled(),
wrongPassword: false, ssoEnabled: open_id.isOpenIDEnabled(),
wrongTotp: false, assetPath: assetPath,
totpEnabled: totp.isTotpEnabled(), appPath: appPath,
ssoEnabled: open_id.isOpenIDEnabled(), });
assetPath: assetPath,
appPath: appPath,
});
}
} }
function setPasswordPage(req: Request, res: Response) { function setPasswordPage(req: Request, res: Response) {

View File

@ -24,48 +24,55 @@
<img class="img-fluid d-block mx-auto" style="height: 8rem;" src="<%= assetPath %>/images/icon-color.svg" aria-hidden="true" draggable="false" > <img class="img-fluid d-block mx-auto" style="height: 8rem;" src="<%= assetPath %>/images/icon-color.svg" aria-hidden="true" draggable="false" >
<h1 class="text-center"><%= t("login.heading") %></h1> <h1 class="text-center"><%= t("login.heading") %></h1>
<form action="login" method="POST"> <% if (ssoEnabled) { %>
<div class="form-group"> <a href="/authenticate" class="google-login-btn">
<label for="password"><%= t("login.password") %></label> <img src="<%= assetPath %>/images/google-logo.svg" alt="Google logo">
<div class="controls"> <%= t("login.sign_in_with_google") %>
<input id="password" name="password" placeholder="" class="form-control" type="password" autofocus> </a>
</div> <% } else { %>
</div> <form action="login" method="POST">
<% if( totpEnabled ) { %>
<div class="form-group"> <div class="form-group">
<label for="totpToken">TOTP Token</label> <label for="password"><%= t("login.password") %></label>
<div class="controls"> <div class="controls">
<input id="totpToken" name="totpToken" placeholder="" class="form-control" type="text" required /> <input id="password" name="password" placeholder="" class="form-control" type="password" autofocus>
</div> </div>
</div> </div>
<% } %> <% if( totpEnabled ) { %>
<div class="form-group">
<% if ( wrongPassword ) { %> <label for="totpToken">TOTP Token</label>
<div class="alert alert-warning"> <div class="controls">
<%= t("login.incorrect-password") %> <input id="totpToken" name="totpToken" placeholder="" class="form-control" type="text" required />
</div> </div>
<% } %>
<% if ( totpEnabled ) { %>
<% if( wrongTotp ) { %>
<div class="alert alert-warning">
<%= t("login.incorrect-totp") %>
</div> </div>
<% } %> <% } %>
<% } %>
<div class="form-group"> <% if ( wrongPassword ) { %>
<div class="checkbox"> <div class="alert alert-warning">
<label class="tn-checkbox"> <%= t("login.incorrect-password") %>
<input id="remember-me" name="rememberMe" value="1" type="checkbox"> </div>
<%= t("login.remember-me") %> <% } %>
</label> <% if ( totpEnabled ) { %>
<% if( wrongTotp ) { %>
<div class="alert alert-warning">
<%= t("login.incorrect-totp") %>
</div>
<% } %>
<% } %>
<div class="form-group">
<div class="checkbox">
<label class="tn-checkbox">
<input id="remember-me" name="rememberMe" value="1" type="checkbox">
<%= t("login.remember-me") %>
</label>
</div>
</div> </div>
</div> <div class="form-group">
<div class="form-group"> <button class="btn btn-success"><%= t("login.button") %></button>
<button class="btn btn-success"><%= t("login.button") %></button> </div>
</div> </form>
</form> <% } %>
</div> </div>
</div> </div>
<script src="<%= appPath %>/login.js" crossorigin type="module"></script> <script src="<%= appPath %>/login.js" crossorigin type="module"></script>

View File

@ -102,7 +102,8 @@
"incorrect-password": "Password is incorrect. Please try again.", "incorrect-password": "Password is incorrect. Please try again.",
"password": "Password", "password": "Password",
"remember-me": "Remember me", "remember-me": "Remember me",
"button": "Login" "button": "Login",
"sign_in_with_google": "Sign in with Google"
}, },
"set_password": { "set_password": {
"title": "Set Password", "title": "Set Password",