Files
Alta-Proxy-Tool/src/session-store.js
T

82 lines
1.8 KiB
JavaScript

'use strict';
const { canonicalizeAltaOrigin } = require('./url-policy');
const MAX_COOKIE_LENGTH = 4096;
function sessionError(code, message) {
const error = new Error(message);
error.code = code;
return error;
}
function validateCookie(cookie) {
if (
typeof cookie !== 'string' ||
cookie.length === 0 ||
cookie.length > MAX_COOKIE_LENGTH ||
/[;\r\n\0]/.test(cookie)
) {
throw sessionError('INVALID_SESSION_COOKIE', 'Invalid Alta session cookie');
}
return cookie;
}
class SessionStore {
#origin = null;
#cookie = null;
#disposed = false;
establish(deploymentOrigin, cookie) {
if (this.#disposed) {
throw sessionError('SESSION_STORE_DISPOSED', 'Alta session store is disposed');
}
// Validate the complete replacement before dropping the current session.
const nextOrigin = canonicalizeAltaOrigin(deploymentOrigin);
const nextCookie = validateCookie(cookie);
this.#origin = nextOrigin;
this.#cookie = nextCookie;
return this.describe();
}
setSession(deploymentOrigin, cookie) {
return this.establish(deploymentOrigin, cookie);
}
requireSession() {
if (this.#disposed || this.#origin === null || this.#cookie === null) {
throw sessionError('NO_ALTA_SESSION', 'No active Alta session');
}
return Object.freeze({ origin: this.#origin, cookie: this.#cookie });
}
describe() {
return Object.freeze({
connected: !this.#disposed && this.#origin !== null && this.#cookie !== null,
origin: !this.#disposed ? this.#origin : null,
});
}
clear() {
this.#cookie = null;
this.#origin = null;
}
dispose() {
this.clear();
this.#disposed = true;
}
}
function createSessionStore() {
return new SessionStore();
}
module.exports = {
MAX_COOKIE_LENGTH,
SessionStore,
createSessionStore,
validateCookie,
};