55 lines
1.8 KiB
JavaScript
55 lines
1.8 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
class Jwk {
|
||
|
#kid; // Key ID
|
||
|
#value; // PEM-encoded public key
|
||
|
#expirationTime; // Expiration time in milliseconds
|
||
|
#createdAt; // UNIX timestamp of object construction
|
||
|
|
||
|
constructor(kid, value, expirationTime = Infinity) {
|
||
|
if(!kid) {
|
||
|
throw new Error("JWK must have a non-empty kid.")
|
||
|
}
|
||
|
|
||
|
if(!value) {
|
||
|
throw new Error("JWK must have a non-empty value.")
|
||
|
}
|
||
|
|
||
|
if(expirationTime < 0) {
|
||
|
throw new Error("JWK must have an expiration time (ms) > 0.")
|
||
|
}
|
||
|
|
||
|
this.#kid = kid;
|
||
|
this.#value = value;
|
||
|
this.#expirationTime = expirationTime;
|
||
|
this.#createdAt = Date.now();
|
||
|
}
|
||
|
|
||
|
get kid() {return this.#kid;}
|
||
|
get value() {return this.#value;}
|
||
|
get expirationTime() {return this.#expirationTime;}
|
||
|
get createdAt() {return this.#createdAt;}
|
||
|
|
||
|
/** Calculates the remaining time until the entry is discarded.
|
||
|
* @returns time from until expiration or 0 if already expired
|
||
|
*/
|
||
|
get remainingTime() {
|
||
|
const elapsedTime = Date.now() - this.createdAt;
|
||
|
return Math.max(0, this.#expirationTime - elapsedTime);
|
||
|
}
|
||
|
|
||
|
// Checks if the entry is expired.
|
||
|
get expired() {
|
||
|
return this.remainingTime <= 0;
|
||
|
}
|
||
|
|
||
|
/** Checks if the Jwk is considered stale given the refresh period. Stale Jwks should be refreshed but may still be used until expiration.
|
||
|
* @param refreshPeriod time period (in ms) before expiration time in which the Jwk should count as stale (but not yet as expired)
|
||
|
* @returns true if the JWK is already expired or will expire within the given refresh period.
|
||
|
*/
|
||
|
stale(refreshPeriod) {
|
||
|
return this.expired || this.remainingTime < refreshPeriod;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = Jwk;
|