85 lines
2.3 KiB
TypeScript
85 lines
2.3 KiB
TypeScript
/**
|
|
* SessionLifetime Value Object
|
|
*
|
|
* Represents the lifetime of an authentication session with expiry tracking.
|
|
* Handles validation of session expiry dates with a configurable buffer window.
|
|
*/
|
|
export class SessionLifetime {
|
|
private readonly expiry: Date | null;
|
|
private readonly bufferMinutes: number;
|
|
|
|
constructor(expiry: Date | null, bufferMinutes: number = 5) {
|
|
if (expiry !== null) {
|
|
if (isNaN(expiry.getTime())) {
|
|
throw new Error('Invalid expiry date provided');
|
|
}
|
|
|
|
// Allow dates within buffer window to support checking expiry of recently expired sessions
|
|
const bufferMs = bufferMinutes * 60 * 1000;
|
|
const expiryWithBuffer = expiry.getTime() + bufferMs;
|
|
if (expiryWithBuffer < Date.now()) {
|
|
throw new Error('Expiry date cannot be in the past');
|
|
}
|
|
}
|
|
|
|
this.expiry = expiry;
|
|
this.bufferMinutes = bufferMinutes;
|
|
}
|
|
|
|
/**
|
|
* Check if the session is expired.
|
|
* Considers the buffer time - sessions within the buffer window are treated as expired.
|
|
*
|
|
* @returns true if expired or expiring soon (within buffer), false otherwise
|
|
*/
|
|
isExpired(): boolean {
|
|
if (this.expiry === null) {
|
|
return false;
|
|
}
|
|
|
|
const bufferMs = this.bufferMinutes * 60 * 1000;
|
|
const expiryWithBuffer = this.expiry.getTime() - bufferMs;
|
|
return Date.now() >= expiryWithBuffer;
|
|
}
|
|
|
|
/**
|
|
* Check if the session is expiring soon (within buffer window).
|
|
*
|
|
* @returns true if expiring within buffer window, false otherwise
|
|
*/
|
|
isExpiringSoon(): boolean {
|
|
if (this.expiry === null) {
|
|
return false;
|
|
}
|
|
|
|
const bufferMs = this.bufferMinutes * 60 * 1000;
|
|
const now = Date.now();
|
|
const expiryTime = this.expiry.getTime();
|
|
const expiryWithBuffer = expiryTime - bufferMs;
|
|
|
|
return now >= expiryWithBuffer && now < expiryTime;
|
|
}
|
|
|
|
/**
|
|
* Get the expiry date.
|
|
*
|
|
* @returns The expiry date or null if no expiration
|
|
*/
|
|
getExpiry(): Date | null {
|
|
return this.expiry;
|
|
}
|
|
|
|
/**
|
|
* Get remaining time until expiry in milliseconds.
|
|
*
|
|
* @returns Milliseconds until expiry, or Infinity if no expiration
|
|
*/
|
|
getRemainingTime(): number {
|
|
if (this.expiry === null) {
|
|
return Infinity;
|
|
}
|
|
|
|
const remaining = this.expiry.getTime() - Date.now();
|
|
return Math.max(0, remaining);
|
|
}
|
|
} |