GUACAMOLE-1383: Merge avoid double-encoding client identifiers within URLs.

This commit is contained in:
Virtually Nick
2021-07-21 10:01:34 -04:00
committed by GitHub
2 changed files with 60 additions and 3 deletions

View File

@@ -239,7 +239,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
ids.push(id); ids.push(id);
// Reconstruct path, updating attached clients via change in route // Reconstruct path, updating attached clients via change in route
$location.path('/client/' + encodeURIComponent(ManagedClientGroup.getIdentifier(ids))); $location.path('/client/' + ManagedClientGroup.getIdentifier(ids));
}; };

View File

@@ -100,6 +100,63 @@ angular.module('navigation').factory('ClientIdentifier', ['$injector',
}; };
/**
* Encodes the given value as base64url, a variant of base64 defined by
* RFC 4648: https://datatracker.ietf.org/doc/html/rfc4648#section-5.
*
* The "base64url" variant is identical to standard base64 except that it
* uses "-" instead of "+", "_" instead of "/", and padding with "=" is
* optional.
*
* @param {string} value
* The string value to encode.
*
* @returns {string}
* The provided string value encoded as unpadded base64url.
*/
var base64urlEncode = function base64urlEncode(value) {
// Translate padded standard base64 to unpadded base64url
return $window.btoa(value).replace(/[+/=]/g,
(str) => ({
'+' : '-',
'/' : '_',
'=' : ''
})[str]
);
};
/**
* Decodes the given base64url or base64 string. The input string may
* contain "=" padding characters, but this is not required.
*
* @param {string} value
* The base64url or base64 value to decode.
*
* @returns {string}
* The result of decoding the provided base64url or base64 string.
*/
var base64urlDecode = function base64urlDecode(value) {
// Add any missing padding (standard base64 requires input strings to
// be multiples of 4 in length, padded using '=')
value += ([
'',
'===',
'==',
'='
])[value.length % 4];
// Translate padded base64url to padded standard base64
return $window.atob(value.replace(/[-_]/g,
(str) => ({
'-' : '+',
'_' : '/'
})[str]
));
};
/** /**
* Converts the given ClientIdentifier or ClientIdentifier-like object to * Converts the given ClientIdentifier or ClientIdentifier-like object to
* a String representation. Any object having the same properties as * a String representation. Any object having the same properties as
@@ -115,7 +172,7 @@ angular.module('navigation').factory('ClientIdentifier', ['$injector',
* or ClientIdentifier-like object. * or ClientIdentifier-like object.
*/ */
ClientIdentifier.toString = function toString(id) { ClientIdentifier.toString = function toString(id) {
return $window.btoa([ return base64urlEncode([
id.id, id.id,
id.type, id.type,
id.dataSource id.dataSource
@@ -137,7 +194,7 @@ angular.module('navigation').factory('ClientIdentifier', ['$injector',
ClientIdentifier.fromString = function fromString(str) { ClientIdentifier.fromString = function fromString(str) {
try { try {
var values = $window.atob(str).split('\0'); var values = base64urlDecode(str).split('\0');
return new ClientIdentifier({ return new ClientIdentifier({
id : values[0], id : values[0],
type : values[1], type : values[1],