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

290
server/node_modules/koa-session/History.md generated vendored Normal file
View File

@@ -0,0 +1,290 @@
6.4.0 / 2023-02-04
==================
**features**
* [[`4cd3bef`](http://github.com/koajs/session/commit/4cd3bef4fc1900b847d2e133e3b2599a711f1aea)] - feat: Add Session.regenerate() method (#221) (Jürg Lehni <<juerg@scratchdisk.com>>)
6.3.1 / 2023-01-03
==================
**fixes**
* [[`e2de39e`](http://github.com/koajs/session/commit/e2de39e6acaf5eef9c8660cbd864ecccaa2b60d0)] - fix: keep crc v3 (#223) (fengmk2 <<fengmk2@gmail.com>>)
6.3.0 / 2023-01-03
==================
**features**
* [[`878669e`](http://github.com/koajs/session/commit/878669ee2c734e3d9902d83f57e21d2113178b79)] - feat: update uuid to v8 (#218) (zhennann <<zhen.nann@icloud.com>>)
**others**
* [[`df2d28f`](http://github.com/koajs/session/commit/df2d28ffb177272739964eb5a503f93db870aa28)] - test: run ci on GitHub Action (#222) (fengmk2 <<fengmk2@gmail.com>>)
6.2.0 / 2021-03-30
==================
**features**
* [[`7cde341`](http://github.com/koajs/session/commit/7cde341db1691ee6885eb1b11ff3a3a3632fd5ce)] - feat: add session.externalKey (#207) (Yiyu He <<dead_horse@qq.com>>)
6.1.0 / 2020-10-08
==================
**features**
* [[`32e3526`](http://github.com/koajs/session/commit/32e352665f2adbcda34d1d990bb6c5d875c0b625)] - feat: add context to external store .get() and .set() options params (#201) (Ngorror <<ngorror@gmail.com>>)
**others**
* [[`f765595`](http://github.com/koajs/session/commit/f76559568bb7f6321cab3f44ae759521deca3dd1)] - chore: Create LICENSE File (#195) (Dominic Egginton <<dominic.egginton@gmail.com>>)
6.0.0 / 2020-04-26
==================
**fixes**
* [[`d34fc8e`](https://github.com/koajs/session/commit/d34fc8e0395bd3dc0c8cceda4374039a4d414060)] - fix: RFC6265 compliant default cookie name (#197) (zacanger <<zac@zacanger.com>>)
* [BREAKING CHANGE]: Default cookie is now `koa.sess` rather than `koa:sess`
5.13.1 / 2020-02-01
==================
**fixes**
* [[`ecd1f5e`](http://github.com/koajs/session/commit/ecd1f5edaa6ff1e77cc461d1107432b394ce21d2)] - fix: don't set any value to sameSite by default (#194) (fengmk2 <<fengmk2@gmail.com>>)
5.13.0 / 2020-02-01
==================
**features**
* [[`cb09a09`](http://github.com/koajs/session/commit/cb09a09cfa4767610d7cc7282a0de2a3a651c6ae)] - feat: support session cookie sameSite options (#193) (fengmk2 <<fengmk2@gmail.com>>)
5.12.3 / 2019-08-23
==================
**fixes**
* [[`909d93f`](http://github.com/koajs/session/commit/909d93fc6b74c6e29b0e83f555f1fc4002a6a108)] - fix: correctly expire cookies for nullified sessions (Justin <<jmitchell38488@users.noreply.github.com>>)
5.12.2 / 2019-07-10
==================
**fixes**
* [[`c23bab4`](http://github.com/koajs/session/commit/c23bab4023b95c65be46b4eeaf089608ddaa738e)] - fix: remvoe unused code (dead-horse <<dead_horse@qq.com>>)
5.12.1 / 2019-07-10
==================
**fixes**
* [[`77968e3`](http://github.com/koajs/session/commit/77968e3ff6fb5d4f4a36665474ccd992fed689ec)] - fix: ensure ctx.session always has value (dead-horse <<dead_horse@qq.com>>)
5.12.0 / 2019-05-17
==================
**features**
* [[`39ca830`](http://github.com/koajs/session/commit/39ca830a99ae7fcab2bd499a1f2a87de53fd1944)] - feat: add the parameter "ctx" to the function "genid" so can get the … (#173) (松松 <<1733458402@qq.com>>)
**others**
* [[`3d57a44`](http://github.com/koajs/session/commit/3d57a443c7e0050d4066c871bf8da2656cda99f1)] - docs: add genid(ctx) in readme (dead-horse <<dead_horse@qq.com>>)
5.11.0 / 2019-04-29
==================
**features**
* [[`b79134d`](http://github.com/koajs/session/commit/b79134d6854173bf46d6703e79636a58f9282e15)] - feat: make sure session id is global unique (#170) (fengmk2 <<fengmk2@gmail.com>>)
**fixes**
* [[`c2b4259`](http://github.com/koajs/session/commit/c2b4259ccef6095cad2f3ff51968b21cea993d13)] - fix: remove package-lock.json (fengmk2 <<fengmk2@gmail.com>>)
**others**
* [[`23ad871`](http://github.com/koajs/session/commit/23ad8718a9a392c0c563893a10b5ca9f6fd70ebe)] - deps: Fix security vulnerabilities from npm audit (#163) (Douglas Wade <<douglas.b.wade@gmail.com>>)
* [[`1600aab`](http://github.com/koajs/session/commit/1600aabdfa6a86973e3fab9f4064c3ed82b10604)] - test: changed "ctx.session is mockable" tests names to more appropriate (#158) (Vitaliy Zaytsev <<teh.kroleg@gmail.com>>)
5.10.1 / 2018-12-18
==================
**features**
* [[`5f12f70`](http://github.com/koajs/session/commit/5f12f7019b4fbb3ce1d495c1c7fb8a234ae16818)] - feat: allow init multi session middleware (#159) (killa <<killa123@126.com>>)
**fixes**
* [[`89c048a`](http://github.com/koajs/session/commit/89c048adc5a64b6c12c87047b766ac34be10af77)] - fix: moved "pedding" package to dev dependencies (#155) (Vitaliy Zaytsev <<teh.kroleg@gmail.com>>)
5.10.0 / 2018-10-29
==================
**features**
* [[`81906f7`](http://github.com/koajs/session/commit/81906f7724ef009dc14686f4990af35c716f6db9)] - feat: support options.externalKey #88 (#149) (Tree Xie <<vicansocanbico@gmail.com>>)
5.9.0 / 2018-08-28
==================
**features**
* [[`7241400`](http://github.com/koajs/session/commit/724140076b65867b1a0cffee4f061971be8751c0)] - feat: Add autoCommit option (#139) (Jonas Galvez <<jonasgalvez@gmail.com>>)
5.8.3 / 2018-08-22
==================
**fixes**
* [[`6f1a41c`](http://github.com/koajs/session/commit/6f1a41cf499f55532f0e7ce0de04d778a0466496)] - fix: session not works (#136) (吖猩 <<whxaxes@qq.com>>)
**others**
* [[`95272ff`](http://github.com/koajs/session/commit/95272ff912af8dd31ae9f038df9540d8b6c019d7)] - fix typo in README.md (#134) (Maples7 <<maples7@163.com>>)
5.8.2 / 2018-07-12
==================
**fixes**
* [[`c487944`](http://github.com/koajs/session/commit/c487944c22056fdd37433bdeab3d665dbd116744)] - fix: Fixes a bug that reset the cookie expire date to the default (1 day) when using browser sessions (maxAge: 'session') (#117) (Adriano <<adrianocola@gmail.com>>)
**others**
* [[`9050605`](http://github.com/koajs/session/commit/90506055366a31205b0895592eb00d43f8d9da28)] - deps: Upgrade debug@^3.1.0 (#107) (Daniel Tseng <<s92f002@hotmail.com>>)
* [[`c48e1e0`](http://github.com/koajs/session/commit/c48e1e054566fe09c81ff50f530c6f230f07c7d5)] - Update Readme.md (#123) (Wellington Soares <<well.cco@gmail.com>>)
5.8.1 / 2018-01-17
==================
**fixes**
* [[`bdb4fd4`](http://github.com/koajs/session/commit/bdb4fd45a7c247c94f0035585104b004e36ec725)] - fix: ensure store expired after cookie (dead-horse <<dead_horse@qq.com>>)
5.8.0 / 2018-01-17
==================
**features**
* [[`bb5f4bf`](http://github.com/koajs/session/commit/bb5f4bf86da802cb37cd5e3a990b5bbcc4f6d144)] - feat: support opts.renew (#111) (Yiyu He <<dead_horse@qq.com>>)
5.7.1 / 2018-01-11
==================
**fixes**
* [[`72fa5fe`](http://github.com/koajs/session/commit/72fa5fec71a8fa3c4e8b75226b401e965d8d31c7)] - fix: emit event in next tick (dead-horse <<dead_horse@qq.com>>)
5.7.0 / 2018-01-09
==================
**features**
* [[`a2401c8`](http://github.com/koajs/session/commit/a2401c85b486a87a4bf933e457b09088496735d7)] - feat: emit event expose ctx (dead-horse <<dead_horse@qq.com>>)
5.6.0 / 2018-01-09
==================
**features**
* [[`f00c1ef`](http://github.com/koajs/session/commit/f00c1ef9857fec52e1aaf981ba9a8e837b3e7ffa)] - feat: emit events when session invalid (#108) (Yiyu He <<dead_horse@qq.com>>)
5.5.1 / 2017-11-17
==================
**others**
* [[`b976b10`](http://github.com/koajs/session/commit/b976b10212f522b675711badb7ce1bc9a909d19d)] - perf: no need to assign opts (#103) (Yiyu He <<dead_horse@qq.com>>)
* [[`c040b59`](http://github.com/koajs/session/commit/c040b5997d35267a3a65becf91e327615ff17fa5)] - chore: fix example bug and use syntactic sugar (#97) (Runrioter Wung <<runrioter@gmail.com>>)
* [[`906277a`](http://github.com/koajs/session/commit/906277a3c9995ed4f07d2cee55e3020af0c75168)] - docs: copyediting (#85) (Nate Silva <<natesilva@users.noreply.github.com>>)
5.5.0 / 2017-08-04
==================
**features**
* [[`ec88cfb`](http://github.com/koajs/session/commit/ec88cfb095ddbfa9a0db465e3f9e459fb6f92bec)] - feat: support options.prefix for external store (#93) (Yiyu He <<dead_horse@qq.com>>)
5.4.0 / 2017-07-03
==================
* feat: opts.genid (#87)
5.3.0 / 2017-06-17
==================
* feat: support rolling (#84)
5.2.0 / 2017-06-15
==================
* feat: support options.ContextStore (#81)
5.1.0 / 2017-06-01
==================
* Create capability to create cookies that expire when browser is close… (#77)
5.0.0 / 2017-03-12
==================
* feat: async/await support (#70)
4.0.1 / 2017-03-01
==================
* fix: ctx.session should be configurable (#67)
4.0.0 / 2017-02-27
==================
* [BREAKING CHANGE]: Drop support for node < 4.
* [BREAKING CHANGE]: Internal implementations are changed, so some private API is changed.
* Change private api `session.save()`, won't set cookie immediately now.
* Remove private api `session.changed()`.
* Remove undocumented property context.sessionKey, can use opts.key instead.
* Change undocumented property context.sessionOptions to getter.
* feat: Support external store by pass options.store.
* feat: Throw when encode session error, consider a breaking change.
* feat: Clean cookie when decode session throw error, ensure next request won't throw again.
* fix: Customize options.decode will check expired now
* docs: Remove Semantics in README because it's not "guest" sessions any more
3.4.0 / 2016-10-15
==================
* fix: add 'session' name for middleware function (#58)
* chore(package): update dependencies
* readme: ignore favicon in example
3.3.1 / 2015-07-08
==================
* code: fix error in variable referencing
3.3.0 / 2015-07-07
==================
* custom encode/decode support
3.2.0 / 2015-06-08
==================
* feat: add opts.valid() and opts.beforeSave() hooks
3.1.1 / 2015-06-04
==================
* deps: upgrade deep-equal to 1.0.0
* fix: allow get session property before enter session middleware
3.1.0 / 2014-12-25
==================
* add session.maxAge
* set expire in cookie value
3.0.0 / 2014-12-11
==================
* improve performance by reduce hiddin class on every request
* refactor with commit() helper
* refactor error handling with finally statement
2.0.0 / 2014-02-17
==================
* changed cookies to be base64-encoded (somewhat breaks backwards compatibility)
1.2.1 / 2014-02-04
==================
* fix saving sessions when a downstream error is thrown
1.2.0 / 2013-12-21
==================
* remove sid from docs
* remove uid2 dep
* change: only save new sessions if populated
* update to use new middleware signature
1.1.0 / 2013-11-15
==================
* add change check, removing the need for `.save()`
* add sane defaults. Closes #4
* add session clearing support. Closes #9
* remove public `.save()`

21
server/node_modules/koa-session/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2014-present Koajs contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

168
server/node_modules/koa-session/Readme.md generated vendored Normal file
View File

@@ -0,0 +1,168 @@
# koa-session
[![NPM version][npm-image]][npm-url]
[![Node.js CI](https://github.com/koajs/session/actions/workflows/nodejs.yml/badge.svg)](https://github.com/koajs/session/actions/workflows/nodejs.yml)
[![npm download][download-image]][download-url]
[npm-image]: https://img.shields.io/npm/v/koa-session.svg?style=flat-square
[npm-url]: https://npmjs.org/package/koa-session
[download-image]: https://img.shields.io/npm/dm/koa-session.svg?style=flat-square
[download-url]: https://npmjs.org/package/koa-session
Simple session middleware for Koa. Defaults to cookie-based sessions and supports external stores.
*Requires Node 8.0.0 or greater for async/await support*
## Installation
```js
$ npm install koa-session
```
## Notice
6.x changed the default cookie key from `koa:sess` to `koa.sess` to ensure `set-cookie` value valid with HTTP spec.[see issue](https://github.com/koajs/session/issues/28). If you want to be compatible with the previous version, you can manually set `config.key` to `koa:sess`.
## Example
View counter example:
```js
const session = require('koa-session');
const Koa = require('koa');
const app = new Koa();
app.keys = ['some secret hurr'];
const CONFIG = {
key: 'koa.sess', /** (string) cookie key (default is koa.sess) */
/** (number || 'session') maxAge in ms (default is 1 days) */
/** 'session' will result in a cookie that expires when session/browser is closed */
/** Warning: If a session cookie is stolen, this cookie will never expire */
maxAge: 86400000,
autoCommit: true, /** (boolean) automatically commit headers (default true) */
overwrite: true, /** (boolean) can overwrite or not (default true) */
httpOnly: true, /** (boolean) httpOnly or not (default true) */
signed: true, /** (boolean) signed or not (default true) */
rolling: false, /** (boolean) Force a session identifier cookie to be set on every response. The expiration is reset to the original maxAge, resetting the expiration countdown. (default is false) */
renew: false, /** (boolean) renew session when session is nearly expired, so we can always keep user logged in. (default is false)*/
secure: true, /** (boolean) secure cookie*/
sameSite: null, /** (string) session cookie sameSite options (default null, don't set it) */
};
app.use(session(CONFIG, app));
// or if you prefer all default config, just use => app.use(session(app));
app.use(ctx => {
// ignore favicon
if (ctx.path === '/favicon.ico') return;
let n = ctx.session.views || 0;
ctx.session.views = ++n;
ctx.body = n + ' views';
});
app.listen(3000);
console.log('listening on port 3000');
```
## API
### Options
The cookie name is controlled by the `key` option, which defaults
to "koa.sess". All other options are passed to `ctx.cookies.get()` and
`ctx.cookies.set()` allowing you to control security, domain, path,
and signing among other settings.
#### Custom `encode/decode` Support
Use `options.encode` and `options.decode` to customize your own encode/decode methods.
### Hooks
- `valid()`: valid session value before use it
- `beforeSave()`: hook before save session
### External Session Stores
The session is stored in a cookie by default, but it has some disadvantages:
- Session is stored on client side unencrypted
- [Browser cookies always have length limits](http://browsercookielimits.squawky.net/)
You can store the session content in external stores (Redis, MongoDB or other DBs) by passing `options.store` with three methods (these need to be async functions):
- `get(key, maxAge, { rolling, ctx })`: get session object by key
- `set(key, sess, maxAge, { rolling, changed, ctx })`: set session object for key, with a `maxAge` (in ms)
- `destroy(key, {ctx})`: destroy session for key
Once you pass `options.store`, session storage is dependent on your external store -- you can't access the session if your external store is down. **Use external session stores only if necessary, avoid using session as a cache, keep the session lean, and store it in a cookie if possible!**
The way of generating external session id is controlled by the `options.genid(ctx)`, which defaults to `uuid.v4()`.
If you want to add prefix for all external session id, you can use `options.prefix`, it will not work if `options.genid(ctx)` present.
If your session store requires data or utilities from context, `opts.ContextStore` is also supported. `ContextStore` must be a class which claims three instance methods demonstrated above. `new ContextStore(ctx)` will be executed on every request.
### Events
`koa-session` will emit event on `app` when session expired or invalid:
- `session:missed`: can't get session value from external store.
- `session:invalid`: session value is invalid.
- `session:expired`: session value is expired.
### Custom External Key
External key is used the cookie by default, but you can use `options.externalKey` to customize your own external key methods. `options.externalKey` with two methods:
- `get(ctx)`: get the external key
- `set(ctx, value)`: set the external key
### Session#isNew
Returns __true__ if the session is new.
```js
if (this.session.isNew) {
// user has not logged in
} else {
// user has already logged in
}
```
### Session#maxAge
Get cookie's maxAge.
### Session#maxAge=
Set cookie's maxAge.
### Session#externalKey
Get session external key, only exist when external session store present.
### Session#save()
Save this session no matter whether it is populated.
### Session#manuallyCommit()
Session headers are auto committed by default. Use this if `autoCommit` is set to `false`.
### Destroying a session
To destroy a session simply set it to `null`:
```js
this.session = null;
```
## License
MIT

151
server/node_modules/koa-session/index.js generated vendored Normal file
View File

@@ -0,0 +1,151 @@
'use strict';
const debug = require('debug')('koa-session');
const ContextSession = require('./lib/context');
const util = require('./lib/util');
const assert = require('assert');
const uuid = require('uuid');
const is = require('is-type-of');
const CONTEXT_SESSION = Symbol('context#contextSession');
const _CONTEXT_SESSION = Symbol('context#_contextSession');
/**
* Initialize session middleware with `opts`:
*
* - `key` session cookie name ["koa.sess"]
* - all other options are passed as cookie options
*
* @param {Object} [opts]
* @param {Application} app, koa application instance
* @api public
*/
module.exports = function(opts, app) {
// session(app[, opts])
if (opts && typeof opts.use === 'function') {
[ app, opts ] = [ opts, app ];
}
// app required
if (!app || typeof app.use !== 'function') {
throw new TypeError('app instance required: `session(opts, app)`');
}
opts = formatOpts(opts);
extendContext(app.context, opts);
return async function session(ctx, next) {
const sess = ctx[CONTEXT_SESSION];
if (sess.store) await sess.initFromExternal();
try {
await next();
} catch (err) {
throw err;
} finally {
if (opts.autoCommit) {
await sess.commit();
}
}
};
};
/**
* format and check session options
* @param {Object} opts session options
* @return {Object} new session options
*
* @api private
*/
function formatOpts(opts) {
opts = opts || {};
// key
opts.key = opts.key || 'koa.sess';
// back-compat maxage
if (!('maxAge' in opts)) opts.maxAge = opts.maxage;
// defaults
if (opts.overwrite == null) opts.overwrite = true;
if (opts.httpOnly == null) opts.httpOnly = true;
// delete null sameSite config
if (opts.sameSite == null) delete opts.sameSite;
if (opts.signed == null) opts.signed = true;
if (opts.autoCommit == null) opts.autoCommit = true;
debug('session options %j', opts);
// setup encoding/decoding
if (typeof opts.encode !== 'function') {
opts.encode = util.encode;
}
if (typeof opts.decode !== 'function') {
opts.decode = util.decode;
}
const store = opts.store;
if (store) {
assert(is.function(store.get), 'store.get must be function');
assert(is.function(store.set), 'store.set must be function');
assert(is.function(store.destroy), 'store.destroy must be function');
}
const externalKey = opts.externalKey;
if (externalKey) {
assert(is.function(externalKey.get), 'externalKey.get must be function');
assert(is.function(externalKey.set), 'externalKey.set must be function');
}
const ContextStore = opts.ContextStore;
if (ContextStore) {
assert(is.class(ContextStore), 'ContextStore must be a class');
assert(is.function(ContextStore.prototype.get), 'ContextStore.prototype.get must be function');
assert(is.function(ContextStore.prototype.set), 'ContextStore.prototype.set must be function');
assert(is.function(ContextStore.prototype.destroy), 'ContextStore.prototype.destroy must be function');
}
if (!opts.genid) {
if (opts.prefix) opts.genid = () => `${opts.prefix}${uuid.v4()}`;
else opts.genid = uuid.v4;
}
return opts;
}
/**
* extend context prototype, add session properties
*
* @param {Object} context koa's context prototype
* @param {Object} opts session options
*
* @api private
*/
function extendContext(context, opts) {
if (context.hasOwnProperty(CONTEXT_SESSION)) {
return;
}
Object.defineProperties(context, {
[CONTEXT_SESSION]: {
get() {
if (this[_CONTEXT_SESSION]) return this[_CONTEXT_SESSION];
this[_CONTEXT_SESSION] = new ContextSession(this, opts);
return this[_CONTEXT_SESSION];
},
},
session: {
get() {
return this[CONTEXT_SESSION].get();
},
set(val) {
this[CONTEXT_SESSION].set(val);
},
configurable: true,
},
sessionOptions: {
get() {
return this[CONTEXT_SESSION].opts;
},
},
});
}

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',
};

46
server/node_modules/koa-session/package.json generated vendored Normal file
View File

@@ -0,0 +1,46 @@
{
"name": "koa-session",
"description": "Koa cookie session middleware with external store support",
"repository": "koajs/session",
"version": "6.4.0",
"keywords": [
"koa",
"middleware",
"session",
"cookie"
],
"files": [
"index.js",
"lib"
],
"devDependencies": {
"benchmark": "^2.1.4",
"eslint": "3",
"eslint-config-egg": "3",
"istanbul": "0",
"koa": "2",
"mm": "^2.1.0",
"mocha": "^5.2.0",
"mz-modules": "^2.0.0",
"pedding": "^1.1.0",
"should": "8",
"supertest": "^3.3.0",
"uid-safe": "^2.1.3"
},
"license": "MIT",
"dependencies": {
"crc": "^3.8.0",
"debug": "^4.3.3",
"is-type-of": "^1.2.1",
"uuid": "^8.3.2"
},
"engines": {
"node": ">=8.0.0"
},
"scripts": {
"test": "npm run lint && NODE_ENV=test mocha --exit --require should --reporter spec test/*.test.js",
"test-cov": "NODE_ENV=test node ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- --exit --require should test/*.test.js",
"ci": "npm run lint && NODE_ENV=test node ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- --exit --require should test/*.test.js",
"lint": "eslint lib test index.js"
}
}