feat: implement OIDC SSO with JIT provisioning

This commit is contained in:
Trevor Mears
2026-01-17 22:52:06 -08:00
parent 82b93602c1
commit 5752f529cb
8 changed files with 273 additions and 39 deletions
+14
View File
@@ -990,6 +990,20 @@
<script src="/js/pages/Settings.js?v=2"></script>
<script src="/js/pages/WatchPage.js?v=1"></script>
<script src="/js/app.js?v=4"></script>
<script>
// Check for SSO token in URL
(function () {
const urlParams = new URLSearchParams(window.location.search);
const token = urlParams.get('token');
if (token) {
console.log('SSO Login successful, saving token...');
localStorage.setItem('authToken', token);
// Clean URL without reloading
const newUrl = window.location.pathname;
window.history.replaceState({}, document.title, newUrl);
}
})();
</script>
</body>
</html>
+37
View File
@@ -195,10 +195,44 @@
<button type="submit" class="btn-login" id="submit-btn">Sign In</button>
</form>
<div class="sso-divider" style="text-align: center; margin: 20px 0; position: relative;">
<span
style="background: var(--color-bg-secondary); padding: 0 10px; color: var(--color-text-secondary); font-size: 14px; position: relative; z-index: 1;">OR</span>
<div
style="position: absolute; top: 50%; left: 0; right: 0; height: 1px; background: var(--color-border); z-index: 0;">
</div>
</div>
<button id="btn-sso-login" class="btn-login"
style="background: transparent; border: 1px solid var(--color-border); color: var(--color-text-primary); display: flex; align-items: center; justify-content: center; gap: 10px;">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"
style="width: 20px; height: 20px;">
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6h-2zm0 8h2v2h-2z" />
</svg>
Sign in with SSO
</button>
</div>
</div>
<script>
// Start SSO Login
document.getElementById('btn-sso-login').addEventListener('click', () => {
window.location.href = '/api/auth/oidc/login';
});
// Check for URL Error params
const urlParams = new URLSearchParams(window.location.search);
const error = urlParams.get('error');
if (error) {
const errorMessage = document.getElementById('error-message');
errorMessage.textContent = error;
errorMessage.classList.add('show');
// Clean URL
window.history.replaceState({}, document.title, window.location.pathname);
}
// Check if setup is required
let isSetupMode = false;
@@ -213,6 +247,9 @@
document.getElementById('submit-btn').textContent = 'Create Account';
document.getElementById('setup-message').classList.add('show');
document.getElementById('password').placeholder = 'Minimum 6 characters';
// Hide SSO in setup mode
document.querySelector('.sso-divider').style.display = 'none';
document.getElementById('btn-sso-login').style.display = 'none';
}
} catch (err) {
console.error('Error checking setup status:', err);