@guarani/jose
Version:
Implementation of the RFCs of the JOSE Working Group.
117 lines (116 loc) • 4.99 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.JsonWebKeySet = void 0;
const invalid_json_web_key_set_exception_1 = require("../exceptions/invalid-json-web-key-set.exception");
const json_web_key_not_found_exception_1 = require("../exceptions/json-web-key-not-found.exception");
const unsupported_algorithm_exception_1 = require("../exceptions/unsupported-algorithm.exception");
const jsonwebkey_algorithms_registry_1 = require("../jwk/algorithms/jsonwebkey-algorithms-registry");
const jsonwebkey_1 = require("../jwk/jsonwebkey");
/**
* Implementation of {@link https://www.rfc-editor.org/rfc/rfc7517.html#section-5 RFC 7517 Section 5}.
*/
class JsonWebKeySet {
/**
* Instantiates a new JSON Web Key Set based on the provided JSON Web Keys.
*
* @param keys JSON Web Keys to be registered at the JSON Web Key Set.
*/
constructor(keys) {
if (!Array.isArray(keys) || keys.length === 0 || keys.some((key) => !(key instanceof jsonwebkey_1.JsonWebKey))) {
throw new TypeError('Invalid parameter "keys".');
}
const identifiers = keys.map((key) => key.kid);
identifiers.forEach((identifier, index) => {
if (identifier === undefined) {
throw new invalid_json_web_key_set_exception_1.InvalidJsonWebKeySetException(`The JSON Web Key at position #${index} does not have a Key Identifier.`);
}
});
if (new Set(identifiers).size !== identifiers.length) {
throw new invalid_json_web_key_set_exception_1.InvalidJsonWebKeySetException('The use of duplicate Key Identifiers is forbidden.');
}
this.keys = keys;
}
/**
* Loads the data of the provided JSON Web Key Parameters into a JSON Web Key based on the Key Type.
*
* @param params Parameters of the JSON Web Key.
* @returns JSON Web Key based on the Key Type of the provided Parameters.
*/
static _loadJsonWebKey(params) {
if (params instanceof jsonwebkey_1.JsonWebKey) {
return params;
}
const alg = jsonwebkey_algorithms_registry_1.JSON_WEB_KEY_ALGORITHMS_REGISTRY[params.kty];
if (alg === undefined) {
throw new unsupported_algorithm_exception_1.UnsupportedAlgorithmException(`Unsupported JSON Web Key Type "${params.kty}".`);
}
return new alg(params);
}
/**
* Loads the provided Parameters into a JSON Web Key Set.
*
* @param params Parameters of the JSON Web Key Set.
* @returns JSON Web Key Set based on the provided Parameters.
*/
static load(params) {
if (params instanceof JsonWebKeySet) {
return params;
}
if (typeof params !== 'object' || params === null) {
throw new TypeError('Invalid parameter "params".');
}
if (!Array.isArray(params.keys) || params.keys.length === 0) {
throw new TypeError('Invalid JSON Web Key Set Parameter "keys".');
}
params.keys.forEach((key, index) => {
if (!jsonwebkey_1.JsonWebKey.isJsonWebKey(key)) {
throw new TypeError(`The item at position #${index} is not a valid JSON Web Key.`);
}
});
const keys = params.keys.map(this._loadJsonWebKey);
return new JsonWebKeySet(keys);
}
/**
* Parses a JSON String into a JSON Web Key Set.
*
* @param data JSON String representation of the JSON Web Key Set to be parsed.
* @returns Instance of a JSON Web Key Set based on the provided JSON String.
*/
static parse(data) {
let parsedData;
try {
parsedData = JSON.parse(data);
}
catch (exc) {
throw new invalid_json_web_key_set_exception_1.InvalidJsonWebKeySetException(null, exc);
}
return this.load(parsedData);
}
/**
* Finds and returns a JSON Web Key based on the provided Parameters.
*
* @param params Parameters of the requested JSON Web Key.
* @returns JSON Web Key based on the required Parameters.
*/
getKeyOrNone(params) {
const keyFinderFn = (key) => {
return Object.entries(params).every(([attr, value]) => Reflect.get(key, attr) === value);
};
return this.keys.find(keyFinderFn);
}
/**
* Returns a JSON Web Key based on the provided Parameters, otherwise, throws an Exception.
*
* @param params JSON Web Key containing the required Parameters.
* @throws {JsonWebKeyNotFoundException} The requested JSON Web Key is not registered at the JSON Web Key Set.
* @returns JSON Web Key based on the required Parameters.
*/
getKeyOrThrow(params) {
const key = this.getKeyOrNone(params);
if (key === undefined) {
throw new json_web_key_not_found_exception_1.JsonWebKeyNotFoundException();
}
return key;
}
}
exports.JsonWebKeySet = JsonWebKeySet;