mirror of
https://github.com/NginxProxyManager/nginx-proxy-manager.git
synced 2025-05-03 04:22:28 +00:00
* add `oidc-config` setting allowing an admin user to configure parameters * modify login page to show another button when oidc is configured * add dependency `openid-client` `v5.4.0` * add backend route to process "OAuth2 Authorization Code" flow initialisation * add backend route to process callback of above flow * sign in the authenticated user with internal jwt token if internal user with email matching the one retrieved from oauth claims exists Note: Only Open ID Connect Discovery is supported which most modern Identity Providers offer. Tested with Authentik 2023.2.2 and Keycloak 18.0.2
98 lines
3.4 KiB
JavaScript
98 lines
3.4 KiB
JavaScript
const $ = require('jquery');
|
|
const Mn = require('backbone.marionette');
|
|
const template = require('./login.ejs');
|
|
const Api = require('../../app/api');
|
|
const i18n = require('../../app/i18n');
|
|
const Tokens = require('../../app/tokens');
|
|
|
|
module.exports = Mn.View.extend({
|
|
template: template,
|
|
className: 'page-single',
|
|
|
|
ui: {
|
|
form: 'form',
|
|
identity: 'input[name="identity"]',
|
|
secret: 'input[name="secret"]',
|
|
error: '.secret-error',
|
|
button: 'button[type=submit]',
|
|
oidcLogin: 'div.login-oidc',
|
|
oidcButton: 'button#login-oidc',
|
|
oidcError: '.oidc-error',
|
|
oidcProvider: 'span.oidc-provider'
|
|
},
|
|
|
|
events: {
|
|
'submit @ui.form': function (e) {
|
|
e.preventDefault();
|
|
this.ui.button.addClass('btn-loading').prop('disabled', true);
|
|
this.ui.error.hide();
|
|
|
|
Api.Tokens.login(this.ui.identity.val(), this.ui.secret.val(), true)
|
|
.then(() => {
|
|
window.location = '/';
|
|
})
|
|
.catch(err => {
|
|
this.ui.error.text(err.message).show();
|
|
this.ui.button.removeClass('btn-loading').prop('disabled', false);
|
|
});
|
|
},
|
|
'click @ui.oidcButton': function(e) {
|
|
this.ui.identity.prop('disabled', true);
|
|
this.ui.secret.prop('disabled', true);
|
|
this.ui.button.prop('disabled', true);
|
|
this.ui.oidcButton.addClass('btn-loading').prop('disabled', true);
|
|
// redirect to initiate oauth flow
|
|
document.location.replace('/api/oidc/');
|
|
},
|
|
},
|
|
|
|
async onRender() {
|
|
// read oauth callback state cookies
|
|
let cookies = document.cookie.split(';'),
|
|
token, expiry, error;
|
|
for (cookie of cookies) {
|
|
let raw = cookie.split('='),
|
|
name = raw[0].trim(),
|
|
value = raw[1];
|
|
if (name === 'npm_oidc') {
|
|
let v = value.split('---');
|
|
token = v[0];
|
|
expiry = v[1];
|
|
}
|
|
if (name === 'npm_oidc_error') {
|
|
console.log(' ERROR 000 > ', value);
|
|
error = decodeURIComponent(value);
|
|
}
|
|
}
|
|
|
|
console.log('login.js event > render', expiry, token);
|
|
// register a newly acquired jwt token following successful oidc authentication
|
|
if (token && expiry && (new Date(Date.parse(decodeURIComponent(expiry)))) > new Date() ) {
|
|
console.log('login.js event > render >>>');
|
|
Tokens.addToken(token);
|
|
document.location.replace('/');
|
|
}
|
|
|
|
// show error message following a failed oidc authentication
|
|
if (error) {
|
|
console.log(' ERROR > ', error);
|
|
this.ui.oidcError.html(error);
|
|
}
|
|
|
|
// fetch oidc configuration and show alternative action button if enabled
|
|
let response = await Api.Settings.getById("oidc-config");
|
|
if (response && response.meta && response.meta.enabled === true) {
|
|
this.ui.oidcProvider.html(response.meta.name);
|
|
this.ui.oidcLogin.show();
|
|
this.ui.oidcError.show();
|
|
}
|
|
},
|
|
|
|
templateContext: {
|
|
i18n: i18n,
|
|
getVersion: function () {
|
|
return $('#login').data('version');
|
|
}
|
|
}
|
|
});
|