Merge pull request #261 from stianst/master
Fixes to cors for js. Improvements to login form for small screens. Fix ng-disabled with kc-read-only forms
This commit is contained in:
commit
df61879fb1
5 changed files with 64 additions and 31 deletions
|
@ -668,12 +668,13 @@ module.directive('onoffswitch', function() {
|
||||||
name: '@',
|
name: '@',
|
||||||
id: '@',
|
id: '@',
|
||||||
ngModel: '=',
|
ngModel: '=',
|
||||||
|
ngDisabled: '=',
|
||||||
kcOnText: '@onText',
|
kcOnText: '@onText',
|
||||||
kcOffText: '@offText'
|
kcOffText: '@offText'
|
||||||
},
|
},
|
||||||
// TODO - The same code acts differently when put into the templateURL. Find why and move the code there.
|
// TODO - The same code acts differently when put into the templateURL. Find why and move the code there.
|
||||||
//templateUrl: "templates/kc-switch.html",
|
//templateUrl: "templates/kc-switch.html",
|
||||||
template: "<span><div class='onoffswitch' tabindex='0'><input type='checkbox' ng-model='ngModel' class='onoffswitch-checkbox' name='{{name}}' id='{{id}}'><label for='{{id}}' class='onoffswitch-label'><span class='onoffswitch-inner'><span class='onoffswitch-active'>{{kcOnText}}</span><span class='onoffswitch-inactive'>{{kcOffText}}</span></span><span class='onoffswitch-switch'></span></label></div></span>",
|
template: "<span><div class='onoffswitch' tabindex='0'><input type='checkbox' ng-model='ngModel' ng-disabled='ngDisabled' class='onoffswitch-checkbox' name='{{name}}' id='{{id}}'><label for='{{id}}' class='onoffswitch-label'><span class='onoffswitch-inner'><span class='onoffswitch-active'>{{kcOnText}}</span><span class='onoffswitch-inactive'>{{kcOffText}}</span></span><span class='onoffswitch-switch'></span></label></div></span>",
|
||||||
compile: function(element, attrs) {
|
compile: function(element, attrs) {
|
||||||
/*
|
/*
|
||||||
We don't want to propagate basic attributes to the root element of directive. Id should be passed to the
|
We don't want to propagate basic attributes to the root element of directive. Id should be passed to the
|
||||||
|
@ -834,20 +835,38 @@ module.directive('kcDropdown', function ($compile, Notifications) {
|
||||||
});
|
});
|
||||||
|
|
||||||
module.directive('kcReadOnly', function() {
|
module.directive('kcReadOnly', function() {
|
||||||
|
var disabled = {};
|
||||||
|
|
||||||
var d = {
|
var d = {
|
||||||
replace : false,
|
replace : false,
|
||||||
link : function(scope, element, attrs) {
|
link : function(scope, element, attrs) {
|
||||||
scope.$watch(attrs.kcReadOnly, function(readOnly, oldValue) {
|
var disable = function(i, e) {
|
||||||
|
if (!e.disabled) {
|
||||||
|
disabled[e.tagName + i] = true;
|
||||||
|
e.disabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var enable = function(i, e) {
|
||||||
|
if (disabled[e.tagName + i]) {
|
||||||
|
e.disabled = false;
|
||||||
|
delete disabled[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.$watch(attrs.kcReadOnly, function(readOnly) {
|
||||||
if (readOnly) {
|
if (readOnly) {
|
||||||
element.find('input').attr('disabled', 'disabled');
|
console.debug('readonly');
|
||||||
element.find('button').attr('disabled', 'disabled');
|
element.find('input').each(disable);
|
||||||
element.find('select').attr('disabled', 'disabled');
|
element.find('button').each(disable);
|
||||||
element.find('textarea').attr('disabled', 'disabled');
|
element.find('select').each(disable);
|
||||||
|
element.find('textarea').each(disable);
|
||||||
} else {
|
} else {
|
||||||
element.find('input').removeAttr('disabled');
|
element.find('input').each(enable);
|
||||||
element.find('button').removeAttr('disabled');
|
element.find('input').each(enable);
|
||||||
element.find('select').removeAttr('disabled');
|
element.find('button').each(enable);
|
||||||
element.find('textarea').removeAttr('disabled');
|
element.find('select').each(enable);
|
||||||
|
element.find('textarea').each(enable);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,6 @@
|
||||||
#kc-login {
|
#kc-login {
|
||||||
float: right;
|
float: right;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#kc-feedback-wrapper {
|
#kc-feedback-wrapper {
|
||||||
|
@ -210,19 +209,19 @@ ol#kc-totp-settings li:first-of-type {
|
||||||
|
|
||||||
height: 37px;
|
height: 37px;
|
||||||
|
|
||||||
margin: 20px;
|
margin: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#kc-header {
|
#kc-header {
|
||||||
padding-left: 40px;
|
padding-left: 15px;
|
||||||
padding-right: 40px;
|
padding-right: 15px;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
float: none;
|
float: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#kc-feedback {
|
#kc-feedback {
|
||||||
padding-left: 40px;
|
padding-left: 15px;
|
||||||
padding-right: 40px;
|
padding-right: 15px;
|
||||||
float: none;
|
float: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,21 +231,26 @@ ol#kc-totp-settings li:first-of-type {
|
||||||
}
|
}
|
||||||
|
|
||||||
#kc-form {
|
#kc-form {
|
||||||
padding-left: 40px;
|
padding-left: 15px;
|
||||||
padding-right: 40px;
|
padding-right: 15px;
|
||||||
float: none;
|
float: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#kc-info-wrapper {
|
#kc-info-wrapper {
|
||||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
margin-top: 20px;
|
margin-top: 15px;
|
||||||
padding-top: 20px;
|
padding-top: 15px;
|
||||||
padding-left: 20px;
|
padding-left: 0px;
|
||||||
padding-right: 40px;
|
padding-right: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#kc-social-providers li {
|
#kc-social-providers li {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.login-pf .container {
|
||||||
|
padding-top: 15px;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -19,7 +19,7 @@ kcLabelClass=control-label
|
||||||
kcLabelWrapperClass=col-xs-12 col-sm-12 col-md-4 col-lg-3
|
kcLabelWrapperClass=col-xs-12 col-sm-12 col-md-4 col-lg-3
|
||||||
kcInputClass=form-control
|
kcInputClass=form-control
|
||||||
kcInputWrapperClass=col-xs-12 col-sm-12 col-md-8 col-lg-9
|
kcInputWrapperClass=col-xs-12 col-sm-12 col-md-8 col-lg-9
|
||||||
kcFormOptionsClass=col-xs-5 col-sm-5 col-md-offset-4 col-md-4 col-lg-offset-3 col-lg-5
|
kcFormOptionsClass=col-xs-4 col-sm-5 col-md-offset-4 col-md-4 col-lg-offset-3 col-lg-5
|
||||||
kcFormButtonsClass=col-xs-7 col-sm-7 col-md-4 col-lg-4 submit
|
kcFormButtonsClass=col-xs-8 col-sm-7 col-md-4 col-lg-4 submit
|
||||||
|
|
||||||
kcInfoAreaClass=col-xs-12 col-sm-4 col-md-4 col-lg-6 details
|
kcInfoAreaClass=col-xs-12 col-sm-4 col-md-4 col-lg-6 details
|
|
@ -38,9 +38,9 @@ var Keycloak = function (options) {
|
||||||
delete sessionStorage.oauthToken;
|
delete sessionStorage.oauthToken;
|
||||||
processCallback(successCallback, errorCallback);
|
processCallback(successCallback, errorCallback);
|
||||||
} else if (options.token) {
|
} else if (options.token) {
|
||||||
setToken(options.token, successCallback);
|
kc.setToken(options.token, successCallback);
|
||||||
} else if (sessionStorage.oauthToken) {
|
} else if (sessionStorage.oauthToken) {
|
||||||
setToken(sessionStorage.oauthToken, successCallback);
|
kc.setToken(sessionStorage.oauthToken, successCallback);
|
||||||
} else if (options.onload) {
|
} else if (options.onload) {
|
||||||
switch (options.onload) {
|
switch (options.onload) {
|
||||||
case 'login-required' :
|
case 'login-required' :
|
||||||
|
@ -58,7 +58,7 @@ var Keycloak = function (options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
kc.logout = function () {
|
kc.logout = function () {
|
||||||
setToken(undefined);
|
kc.setToken(undefined);
|
||||||
window.location.href = kc.createLogoutUrl();
|
window.location.href = kc.createLogoutUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,8 +164,10 @@ var Keycloak = function (options) {
|
||||||
var url = kc.getRealmUrl() + '/tokens/access/codes';
|
var url = kc.getRealmUrl() + '/tokens/access/codes';
|
||||||
|
|
||||||
var req = new XMLHttpRequest();
|
var req = new XMLHttpRequest();
|
||||||
req.open('POST', url, true, options.clientId, options.clientSecret);
|
req.open('POST', url, true);
|
||||||
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
||||||
|
req.setRequestHeader('Authorization', 'Basic ' + btoa(options.clientId + ':' + options.clientSecret));
|
||||||
|
req.withCredentials = true;
|
||||||
|
|
||||||
req.onreadystatechange = function () {
|
req.onreadystatechange = function () {
|
||||||
if (req.readyState == 4) {
|
if (req.readyState == 4) {
|
||||||
|
@ -197,12 +199,12 @@ var Keycloak = function (options) {
|
||||||
|
|
||||||
kc.tokenParsed = JSON.parse(atob(token.split('.')[1]));
|
kc.tokenParsed = JSON.parse(atob(token.split('.')[1]));
|
||||||
kc.authenticated = true;
|
kc.authenticated = true;
|
||||||
kc.username = kc.tokenParsed.sub;
|
kc.subject = kc.tokenParsed.sub;
|
||||||
kc.realmAccess = kc.tokenParsed.realm_access;
|
kc.realmAccess = kc.tokenParsed.realm_access;
|
||||||
kc.resourceAccess = kc.tokenParsed.resource_access;
|
kc.resourceAccess = kc.tokenParsed.resource_access;
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
successCallback && successCallback({ authenticated: kc.authenticated, username: kc.username });
|
successCallback && successCallback({ authenticated: kc.authenticated, subject: kc.subject });
|
||||||
}, 0);
|
}, 0);
|
||||||
} else {
|
} else {
|
||||||
delete sessionStorage.oauthToken;
|
delete sessionStorage.oauthToken;
|
||||||
|
|
|
@ -38,6 +38,7 @@ import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.HeaderParam;
|
import javax.ws.rs.HeaderParam;
|
||||||
import javax.ws.rs.NotAcceptableException;
|
import javax.ws.rs.NotAcceptableException;
|
||||||
import javax.ws.rs.NotAuthorizedException;
|
import javax.ws.rs.NotAuthorizedException;
|
||||||
|
import javax.ws.rs.OPTIONS;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
@ -343,6 +344,13 @@ public class TokenService {
|
||||||
return processLogin(clientId, scopeParam, state, redirect, formData);
|
return processLogin(clientId, scopeParam, state, redirect, formData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Path("access/codes")
|
||||||
|
@OPTIONS
|
||||||
|
@Produces("application/json")
|
||||||
|
public Response accessCodeToTokenPreflight() {
|
||||||
|
return Cors.add(request, Response.ok()).auth().preflight().build();
|
||||||
|
}
|
||||||
|
|
||||||
@Path("access/codes")
|
@Path("access/codes")
|
||||||
@POST
|
@POST
|
||||||
@Produces("application/json")
|
@Produces("application/json")
|
||||||
|
@ -418,7 +426,7 @@ public class TokenService {
|
||||||
.generateIDToken()
|
.generateIDToken()
|
||||||
.generateRefreshToken().build();
|
.generateRefreshToken().build();
|
||||||
|
|
||||||
return Cors.add(request, Response.ok(res)).allowedOrigins(client).allowedMethods("POST").build();
|
return Cors.add(request, Response.ok(res)).auth().allowedOrigins(client).allowedMethods("POST").build();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ClientModel authorizeClient(String authorizationHeader) {
|
protected ClientModel authorizeClient(String authorizationHeader) {
|
||||||
|
|
Loading…
Reference in a new issue