description and source-code(server, options, next) => {
// Validate options and apply defaults
const settings = Hoek.applyToDefaults(internals.defaults, options);
Hoek.assert(!settings.cookieOptions.encoding, 'Cannot override cookie encoding');
const rawCookieOptions = Hoek.clone(settings.cookieOptions);
settings.cookieOptions.encoding = 'iron';
rawCookieOptions.encoding = 'none';
if (settings.customSessionIDGenerator) {
Hoek.assert(typeof settings.customSessionIDGenerator === 'function', 'customSessionIDGenerator should be a function');
}
// Configure cookie
server.state(settings.name, settings.cookieOptions);
// Decorate the server with yar object.
const getState = () => {
return {};
};
server.decorate('request', 'yar', getState, {
apply: true
});
// Setup session store
const cache = server.cache(settings.cache);
// Pre auth
server.ext('onPreAuth', (request, reply) => {
// If this route configuration indicates to skip, do nothing.
if (Hoek.reach(request, 'route.settings.plugins.yar.skip')) {
return reply.continue();
}
const generateSessionID = () => {
const id = settings.customSessionIDGenerator ? settings.customSessionIDGenerator(request) : Uuid.v4();
Hoek.assert(typeof id === 'string', 'Session ID should be a string');
return id;
};
// Load session data from cookie
const load = () => {
request.yar = Object.assign(request.yar, request.state[settings.name]);
if (request.yar.id) {
request.yar._isModified = false;
if (!settings.errorOnCacheNotReady && !cache.isReady() && !request.yar._store) {
request.log('Cache is not ready: not loading sessions from cache');
request.yar._store = {};
}
if (request.yar._store) {
return decorate();
}
request.yar._store = {};
return cache.get(request.yar.id, (err, value, cached) => {
if (err) {
return decorate(err);
}
if (cached && cached.item) {
request.yar._store = cached.item;
}
return decorate();
});
}
request.yar.id = generateSessionID();
request.yar._store = {};
request.yar._isModified = settings.storeBlank;
decorate();
};
const decorate = (err) => {
if (request.yar._store._lazyKeys) {
request.yar._isLazy = true; // Default to lazy mode if previously set
request.yar._store._lazyKeys.forEach((key) => {
request.yar[key] = request.yar._store[key];
delete request.yar._store[key];
});
}
request.yar.reset = () => {
cache.drop(request.yar.id, () => {});
request.yar.id = generateSessionID();
request.yar._store = {};
request.yar._isModified = true;
};
request.yar.get = (key, clear) => {
const value = request.yar._store[key];
if (clear) {
request.yar.clear(key);
}
return value;
};
request.yar.set = (key, value) => {
Hoek.assert(key, 'Missing key');
Hoek.assert(typeof key === 'string' || (typeof key === 'object' && value === undefined), 'Invalid yar.set() arguments
');
request.yar._isModified = true;
if (typeof key === 'string') {
// convert key of type string into an object, for consistency.
const holder = {};
holder[key] = value;
key = holder;
}
Object. ...