node_modules ignore

This commit is contained in:
2025-05-08 23:43:47 +02:00
parent e19d52f172
commit 4574544c9f
65041 changed files with 10593536 additions and 0 deletions

345
server/node_modules/koa-session/lib/context.js generated vendored Normal file
View File

@@ -0,0 +1,345 @@
'use strict';
const debug = require('debug')('koa-session:context');
const Session = require('./session');
const util = require('./util');
const COOKIE_EXP_DATE = new Date(util.CookieDateEpoch);
const ONE_DAY = 24 * 60 * 60 * 1000;
class ContextSession {
/**
* context session constructor
* @api public
*/
constructor(ctx, opts) {
this.ctx = ctx;
this.app = ctx.app;
this.opts = Object.assign({}, opts);
this.store = this.opts.ContextStore ? new this.opts.ContextStore(ctx) : this.opts.store;
}
/**
* internal logic of `ctx.session`
* @return {Session} session object
*
* @api public
*/
get() {
const session = this.session;
// already retrieved
if (session) return session;
// unset
if (session === false) return null;
// create an empty session or init from cookie
this.store ? this.create() : this.initFromCookie();
return this.session;
}
/**
* internal logic of `ctx.session=`
* @param {Object} val session object
*
* @api public
*/
set(val) {
if (val === null) {
this.session = false;
return;
}
if (typeof val === 'object') {
// use the original `externalKey` if exists to avoid waste storage
this.create(val, this.externalKey);
return;
}
throw new Error('this.session can only be set as null or an object.');
}
/**
* init session from external store
* will be called in the front of session middleware
*
* @api public
*/
async initFromExternal() {
debug('init from external');
const ctx = this.ctx;
const opts = this.opts;
let externalKey;
if (opts.externalKey) {
externalKey = opts.externalKey.get(ctx);
debug('get external key from custom %s', externalKey);
} else {
externalKey = ctx.cookies.get(opts.key, opts);
debug('get external key from cookie %s', externalKey);
}
if (!externalKey) {
// create a new `externalKey`
this.create();
return;
}
const json = await this.store.get(externalKey, opts.maxAge, { ctx, rolling: opts.rolling });
if (!this.valid(json, externalKey)) {
// create a new `externalKey`
this.create();
return;
}
// create with original `externalKey`
this.create(json, externalKey);
this.prevHash = util.hash(this.session.toJSON());
}
/**
* init session from cookie
* @api private
*/
initFromCookie() {
debug('init from cookie');
const ctx = this.ctx;
const opts = this.opts;
const cookie = ctx.cookies.get(opts.key, opts);
if (!cookie) {
this.create();
return;
}
let json;
debug('parse %s', cookie);
try {
json = opts.decode(cookie);
} catch (err) {
// backwards compatibility:
// create a new session if parsing fails.
// new Buffer(string, 'base64') does not seem to crash
// when `string` is not base64-encoded.
// but `JSON.parse(string)` will crash.
debug('decode %j error: %s', cookie, err);
if (!(err instanceof SyntaxError)) {
// clean this cookie to ensure next request won't throw again
ctx.cookies.set(opts.key, '', opts);
// ctx.onerror will unset all headers, and set those specified in err
err.headers = {
'set-cookie': ctx.response.get('set-cookie'),
};
throw err;
}
this.create();
return;
}
debug('parsed %j', json);
if (!this.valid(json)) {
this.create();
return;
}
// support access `ctx.session` before session middleware
this.create(json);
this.prevHash = util.hash(this.session.toJSON());
}
/**
* verify session(expired or )
* @param {Object} value session object
* @param {Object} key session externalKey(optional)
* @return {Boolean} valid
* @api private
*/
valid(value, key) {
const ctx = this.ctx;
if (!value) {
this.emit('missed', { key, value, ctx });
return false;
}
if (value._expire && value._expire < Date.now()) {
debug('expired session');
this.emit('expired', { key, value, ctx });
return false;
}
const valid = this.opts.valid;
if (typeof valid === 'function' && !valid(ctx, value)) {
// valid session value fail, ignore this session
debug('invalid session');
this.emit('invalid', { key, value, ctx });
return false;
}
return true;
}
/**
* @param {String} event event name
* @param {Object} data event data
* @api private
*/
emit(event, data) {
setImmediate(() => {
this.app.emit(`session:${event}`, data);
});
}
/**
* create a new session and attach to ctx.sess
*
* @param {Object} [val] session data
* @param {String} [externalKey] session external key
* @api private
*/
create(val, externalKey) {
debug('create session with val: %j externalKey: %s', val, externalKey);
if (this.store) this.externalKey = externalKey || this.opts.genid && this.opts.genid(this.ctx);
this.session = new Session(this, val, this.externalKey);
}
/**
* Commit the session changes or removal.
*
* @api public
*/
async commit({ save = false, regenerate = false } = {}) {
const session = this.session;
const opts = this.opts;
const ctx = this.ctx;
// not accessed
if (undefined === session) return;
// removed
if (session === false) {
await this.remove();
return;
}
if (regenerate) {
await this.remove();
if (this.store) this.externalKey = opts.genid && opts.genid(ctx);
}
// force save session when `session._requireSave` set
const reason = save || regenerate || session._requireSave ? 'force' : this._shouldSaveSession();
debug('should save session: %s', reason);
if (!reason) return;
if (typeof opts.beforeSave === 'function') {
debug('before save');
opts.beforeSave(ctx, session);
}
const changed = reason === 'changed';
await this.save(changed);
}
_shouldSaveSession() {
const prevHash = this.prevHash;
const session = this.session;
// do nothing if new and not populated
const json = session.toJSON();
if (!prevHash && !Object.keys(json).length) return '';
// save if session changed
const changed = prevHash !== util.hash(json);
if (changed) return 'changed';
// save if opts.rolling set
if (this.opts.rolling) return 'rolling';
// save if opts.renew and session will expired
if (this.opts.renew) {
const expire = session._expire;
const maxAge = session.maxAge;
// renew when session will expired in maxAge / 2
if (expire && maxAge && expire - Date.now() < maxAge / 2) return 'renew';
}
return '';
}
/**
* remove session
* @api private
*/
async remove() {
// Override the default options so that we can properly expire the session cookies
const opts = Object.assign({}, this.opts, {
expires: COOKIE_EXP_DATE,
maxAge: false,
});
const ctx = this.ctx;
const key = opts.key;
const externalKey = this.externalKey;
if (externalKey) await this.store.destroy(externalKey, { ctx });
ctx.cookies.set(key, '', opts);
}
/**
* save session
* @api private
*/
async save(changed) {
const opts = this.opts;
const key = opts.key;
const externalKey = this.externalKey;
let json = this.session.toJSON();
// set expire for check
let maxAge = opts.maxAge ? opts.maxAge : ONE_DAY;
if (maxAge === 'session') {
// do not set _expire in json if maxAge is set to 'session'
// also delete maxAge from options
opts.maxAge = undefined;
json._session = true;
} else {
// set expire for check
json._expire = maxAge + Date.now();
json._maxAge = maxAge;
}
// save to external store
if (externalKey) {
debug('save %j to external key %s', json, externalKey);
if (typeof maxAge === 'number') {
// ensure store expired after cookie
maxAge += 10000;
}
await this.store.set(externalKey, json, maxAge, {
changed,
ctx: this.ctx,
rolling: opts.rolling,
});
if (opts.externalKey) {
opts.externalKey.set(this.ctx, externalKey);
} else {
this.ctx.cookies.set(key, externalKey, opts);
}
return;
}
// save to cookie
debug('save %j to cookie', json);
json = opts.encode(json);
debug('save %s', json);
this.ctx.cookies.set(key, json, opts);
}
}
module.exports = ContextSession;

163
server/node_modules/koa-session/lib/session.js generated vendored Normal file
View File

@@ -0,0 +1,163 @@
'use strict';
/**
* Session model.
*/
const inspect = Symbol.for('nodejs.util.inspect.custom');
class Session {
/**
* Session constructor
* @param {Context} ctx
* @param {Object} obj
* @api private
*/
constructor(sessionContext, obj, externalKey) {
this._sessCtx = sessionContext;
this._ctx = sessionContext.ctx;
this._externalKey = externalKey;
if (!obj) {
this.isNew = true;
} else {
for (const k in obj) {
// restore maxAge from store
if (k === '_maxAge') this._ctx.sessionOptions.maxAge = obj._maxAge;
else if (k === '_session') this._ctx.sessionOptions.maxAge = 'session';
else this[k] = obj[k];
}
}
}
/**
* JSON representation of the session.
*
* @return {Object}
* @api public
*/
toJSON() {
const obj = {};
Object.keys(this).forEach(key => {
if (key === 'isNew') return;
if (key[0] === '_') return;
obj[key] = this[key];
});
return obj;
}
/**
*
* alias to `toJSON`
* @api public
*/
[inspect]() {
return this.toJSON();
}
/**
* Return how many values there are in the session object.
* Used to see if it's "populated".
*
* @return {Number}
* @api public
*/
get length() {
return Object.keys(this.toJSON()).length;
}
/**
* populated flag, which is just a boolean alias of .length.
*
* @return {Boolean}
* @api public
*/
get populated() {
return !!this.length;
}
/**
* get session maxAge
*
* @return {Number}
* @api public
*/
get maxAge() {
return this._ctx.sessionOptions.maxAge;
}
/**
* set session maxAge
*
* @param {Number}
* @api public
*/
set maxAge(val) {
this._ctx.sessionOptions.maxAge = val;
// maxAge changed, must save to cookie and store
this._requireSave = true;
}
/**
* get session external key
* only exist if opts.store present
*/
get externalKey() {
return this._externalKey;
}
/**
* save this session no matter whether it is populated
*
* @param {Function} callback the optional function to call after saving the session
* @api public
*/
save(callback) {
return this.commit({ save: true }, callback);
}
/**
* regenerate this session
*
* @param {Function} callback the optional function to call after regenerating the session
* @api public
*/
regenerate(callback) {
return this.commit({ regenerate: true }, callback);
}
/**
* commit this session's headers if autoCommit is set to false
*
* @api public
*/
manuallyCommit() {
return this.commit();
}
commit(options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
const promise = this._sessCtx.commit(options);
if (callback) {
promise.then(() => callback(), callback);
} else {
return promise;
}
}
}
module.exports = Session;

39
server/node_modules/koa-session/lib/util.js generated vendored Normal file
View File

@@ -0,0 +1,39 @@
'use strict';
const crc = require('crc').crc32;
module.exports = {
/**
* Decode the base64 cookie value to an object.
*
* @param {String} string
* @return {Object}
* @api private
*/
decode(string) {
const body = Buffer.from(string, 'base64').toString('utf8');
const json = JSON.parse(body);
return json;
},
/**
* Encode an object into a base64-encoded JSON string.
*
* @param {Object} body
* @return {String}
* @api private
*/
encode(body) {
body = JSON.stringify(body);
return Buffer.from(body).toString('base64');
},
hash(sess) {
return crc(JSON.stringify(sess));
},
CookieDateEpoch: 'Thu, 01 Jan 1970 00:00:00 GMT',
};