Used ejs to conditionally render login/logout text. Main index file is now index.ejs

This commit is contained in:
Aravind142857
2023-06-27 00:48:19 -05:00
parent 7641f45abf
commit decfc44592
46 changed files with 5740 additions and 12 deletions

73
node_modules/.package-lock.json generated vendored
View File

@@ -525,6 +525,26 @@
"node": ">= 0.6"
}
},
"node_modules/cookie-parser": {
"version": "1.4.6",
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz",
"integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==",
"dependencies": {
"cookie": "0.4.1",
"cookie-signature": "1.0.6"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/cookie-parser/node_modules/cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
@@ -675,6 +695,32 @@
"node": ">= 0.10.0"
}
},
"node_modules/express-session": {
"version": "1.17.3",
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz",
"integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==",
"dependencies": {
"cookie": "0.4.2",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "~2.0.0",
"on-headers": "~1.0.2",
"parseurl": "~1.3.3",
"safe-buffer": "5.2.1",
"uid-safe": "~2.1.5"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/express-session/node_modules/cookie": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/express/node_modules/body-parser": {
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
@@ -1528,6 +1574,14 @@
"node": ">= 0.8"
}
},
"node_modules/on-headers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -1803,6 +1857,14 @@
}
]
},
"node_modules/random-bytes": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
"integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -2287,6 +2349,17 @@
"node": ">= 0.6"
}
},
"node_modules/uid-safe": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
"integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
"dependencies": {
"random-bytes": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",

100
node_modules/cookie-parser/HISTORY.md generated vendored Normal file
View File

@@ -0,0 +1,100 @@
1.4.6 / 2021-11-16
==================
* deps: cookie@0.4.1
1.4.5 / 2020-03-14
==================
* deps: cookie@0.4.0
1.4.4 / 2019-02-12
==================
* perf: normalize `secret` argument only once
1.4.3 / 2016-05-26
==================
* deps: cookie@0.3.1
- perf: use for loop in parse
1.4.2 / 2016-05-20
==================
* deps: cookie@0.2.4
- perf: enable strict mode
- perf: use for loop in parse
- perf: use string concatenation for serialization
1.4.1 / 2016-01-11
==================
* deps: cookie@0.2.3
* perf: enable strict mode
1.4.0 / 2015-09-18
==================
* Accept array of secrets in addition to a single secret
* Fix `JSONCookie` to return `undefined` for non-string arguments
* Fix `signedCookie` to return `undefined` for non-string arguments
* deps: cookie@0.2.2
1.3.5 / 2015-05-19
==================
* deps: cookie@0.1.3
- Slight optimizations
1.3.4 / 2015-02-15
==================
* deps: cookie-signature@1.0.6
1.3.3 / 2014-09-05
==================
* deps: cookie-signature@1.0.5
1.3.2 / 2014-06-26
==================
* deps: cookie-signature@1.0.4
- fix for timing attacks
1.3.1 / 2014-06-17
==================
* actually export `signedCookie`
1.3.0 / 2014-06-17
==================
* add `signedCookie` export for single cookie unsigning
1.2.0 / 2014-06-17
==================
* export parsing functions
* `req.cookies` and `req.signedCookies` are now plain objects
* slightly faster parsing of many cookies
1.1.0 / 2014-05-12
==================
* Support for NodeJS version 0.8
* deps: cookie@0.1.2
- Fix for maxAge == 0
- made compat with expires field
- tweak maxAge NaN error message
1.0.1 / 2014-02-20
==================
* add missing dependencies
1.0.0 / 2014-02-15
==================
* Genesis from `connect`

23
node_modules/cookie-parser/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,23 @@
(The MIT License)
Copyright (c) 2014 TJ Holowaychuk <tj@vision-media.ca>
Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
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.

119
node_modules/cookie-parser/README.md generated vendored Normal file
View File

@@ -0,0 +1,119 @@
# cookie-parser
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Build Status][ci-image]][ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]
Parse `Cookie` header and populate `req.cookies` with an object keyed by the
cookie names. Optionally you may enable signed cookie support by passing a
`secret` string, which assigns `req.secret` so it may be used by other
middleware.
## Installation
```sh
$ npm install cookie-parser
```
## API
```js
var cookieParser = require('cookie-parser')
```
### cookieParser(secret, options)
Create a new cookie parser middleware function using the given `secret` and
`options`.
- `secret` a string or array used for signing cookies. This is optional and if
not specified, will not parse signed cookies. If a string is provided, this
is used as the secret. If an array is provided, an attempt will be made to
unsign the cookie with each secret in order.
- `options` an object that is passed to `cookie.parse` as the second option. See
[cookie](https://www.npmjs.org/package/cookie) for more information.
- `decode` a function to decode the value of the cookie
The middleware will parse the `Cookie` header on the request and expose the
cookie data as the property `req.cookies` and, if a `secret` was provided, as
the property `req.signedCookies`. These properties are name value pairs of the
cookie name to cookie value.
When `secret` is provided, this module will unsign and validate any signed cookie
values and move those name value pairs from `req.cookies` into `req.signedCookies`.
A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies
that fail signature validation will have the value `false` instead of the tampered
value.
In addition, this module supports special "JSON cookies". These are cookie where
the value is prefixed with `j:`. When these values are encountered, the value will
be exposed as the result of `JSON.parse`. If parsing fails, the original value will
remain.
### cookieParser.JSONCookie(str)
Parse a cookie value as a JSON cookie. This will return the parsed JSON value
if it was a JSON cookie, otherwise, it will return the passed value.
### cookieParser.JSONCookies(cookies)
Given an object, this will iterate over the keys and call `JSONCookie` on each
value, replacing the original value with the parsed value. This returns the
same object that was passed in.
### cookieParser.signedCookie(str, secret)
Parse a cookie value as a signed cookie. This will return the parsed unsigned
value if it was a signed cookie and the signature was valid. If the value was
not signed, the original value is returned. If the value was signed but the
signature could not be validated, `false` is returned.
The `secret` argument can be an array or string. If a string is provided, this
is used as the secret. If an array is provided, an attempt will be made to
unsign the cookie with each secret in order.
### cookieParser.signedCookies(cookies, secret)
Given an object, this will iterate over the keys and check if any value is a
signed cookie. If it is a signed cookie and the signature is valid, the key
will be deleted from the object and added to the new object that is returned.
The `secret` argument can be an array or string. If a string is provided, this
is used as the secret. If an array is provided, an attempt will be made to
unsign the cookie with each secret in order.
## Example
```js
var express = require('express')
var cookieParser = require('cookie-parser')
var app = express()
app.use(cookieParser())
app.get('/', function (req, res) {
// Cookies that have not been signed
console.log('Cookies: ', req.cookies)
// Cookies that have been signed
console.log('Signed Cookies: ', req.signedCookies)
})
app.listen(8080)
// curl command that sends an HTTP request with two cookies
// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
```
## License
[MIT](LICENSE)
[ci-image]: https://badgen.net/github/checks/expressjs/cookie-parser/master?label=ci
[ci-url]: https://github.com/expressjs/cookie-parser/actions?query=workflow%3Aci
[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master
[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
[npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser
[npm-url]: https://npmjs.org/package/cookie-parser
[npm-version-image]: https://badgen.net/npm/v/cookie-parser

182
node_modules/cookie-parser/index.js generated vendored Normal file
View File

@@ -0,0 +1,182 @@
/*!
* cookie-parser
* Copyright(c) 2014 TJ Holowaychuk
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var cookie = require('cookie')
var signature = require('cookie-signature')
/**
* Module exports.
* @public
*/
module.exports = cookieParser
module.exports.JSONCookie = JSONCookie
module.exports.JSONCookies = JSONCookies
module.exports.signedCookie = signedCookie
module.exports.signedCookies = signedCookies
/**
* Parse Cookie header and populate `req.cookies`
* with an object keyed by the cookie names.
*
* @param {string|array} [secret] A string (or array of strings) representing cookie signing secret(s).
* @param {Object} [options]
* @return {Function}
* @public
*/
function cookieParser (secret, options) {
var secrets = !secret || Array.isArray(secret)
? (secret || [])
: [secret]
return function cookieParser (req, res, next) {
if (req.cookies) {
return next()
}
var cookies = req.headers.cookie
req.secret = secrets[0]
req.cookies = Object.create(null)
req.signedCookies = Object.create(null)
// no cookies
if (!cookies) {
return next()
}
req.cookies = cookie.parse(cookies, options)
// parse signed cookies
if (secrets.length !== 0) {
req.signedCookies = signedCookies(req.cookies, secrets)
req.signedCookies = JSONCookies(req.signedCookies)
}
// parse JSON cookies
req.cookies = JSONCookies(req.cookies)
next()
}
}
/**
* Parse JSON cookie string.
*
* @param {String} str
* @return {Object} Parsed object or undefined if not json cookie
* @public
*/
function JSONCookie (str) {
if (typeof str !== 'string' || str.substr(0, 2) !== 'j:') {
return undefined
}
try {
return JSON.parse(str.slice(2))
} catch (err) {
return undefined
}
}
/**
* Parse JSON cookies.
*
* @param {Object} obj
* @return {Object}
* @public
*/
function JSONCookies (obj) {
var cookies = Object.keys(obj)
var key
var val
for (var i = 0; i < cookies.length; i++) {
key = cookies[i]
val = JSONCookie(obj[key])
if (val) {
obj[key] = val
}
}
return obj
}
/**
* Parse a signed cookie string, return the decoded value.
*
* @param {String} str signed cookie string
* @param {string|array} secret
* @return {String} decoded value
* @public
*/
function signedCookie (str, secret) {
if (typeof str !== 'string') {
return undefined
}
if (str.substr(0, 2) !== 's:') {
return str
}
var secrets = !secret || Array.isArray(secret)
? (secret || [])
: [secret]
for (var i = 0; i < secrets.length; i++) {
var val = signature.unsign(str.slice(2), secrets[i])
if (val !== false) {
return val
}
}
return false
}
/**
* Parse signed cookies, returning an object containing the decoded key/value
* pairs, while removing the signed key from obj.
*
* @param {Object} obj
* @param {string|array} secret
* @return {Object}
* @public
*/
function signedCookies (obj, secret) {
var cookies = Object.keys(obj)
var dec
var key
var ret = Object.create(null)
var val
for (var i = 0; i < cookies.length; i++) {
key = cookies[i]
val = obj[key]
dec = signedCookie(val, secret)
if (val !== dec) {
ret[key] = dec
delete obj[key]
}
}
return ret
}

View File

@@ -0,0 +1,128 @@
0.4.1 / 2020-04-21
==================
* Fix `maxAge` option to reject invalid values
0.4.0 / 2019-05-15
==================
* Add `SameSite=None` support
0.3.1 / 2016-05-26
==================
* Fix `sameSite: true` to work with draft-7 clients
- `true` now sends `SameSite=Strict` instead of `SameSite`
0.3.0 / 2016-05-26
==================
* Add `sameSite` option
- Replaces `firstPartyOnly` option, never implemented by browsers
* Improve error message when `encode` is not a function
* Improve error message when `expires` is not a `Date`
0.2.4 / 2016-05-20
==================
* perf: enable strict mode
* perf: use for loop in parse
* perf: use string concatination for serialization
0.2.3 / 2015-10-25
==================
* Fix cookie `Max-Age` to never be a floating point number
0.2.2 / 2015-09-17
==================
* Fix regression when setting empty cookie value
- Ease the new restriction, which is just basic header-level validation
* Fix typo in invalid value errors
0.2.1 / 2015-09-17
==================
* Throw on invalid values provided to `serialize`
- Ensures the resulting string is a valid HTTP header value
0.2.0 / 2015-08-13
==================
* Add `firstPartyOnly` option
* Throw better error for invalid argument to parse
* perf: hoist regular expression
0.1.5 / 2015-09-17
==================
* Fix regression when setting empty cookie value
- Ease the new restriction, which is just basic header-level validation
* Fix typo in invalid value errors
0.1.4 / 2015-09-17
==================
* Throw better error for invalid argument to parse
* Throw on invalid values provided to `serialize`
- Ensures the resulting string is a valid HTTP header value
0.1.3 / 2015-05-19
==================
* Reduce the scope of try-catch deopt
* Remove argument reassignments
0.1.2 / 2014-04-16
==================
* Remove unnecessary files from npm package
0.1.1 / 2014-02-23
==================
* Fix bad parse when cookie value contained a comma
* Fix support for `maxAge` of `0`
0.1.0 / 2013-05-01
==================
* Add `decode` option
* Add `encode` option
0.0.6 / 2013-04-08
==================
* Ignore cookie parts missing `=`
0.0.5 / 2012-10-29
==================
* Return raw cookie value if value unescape errors
0.0.4 / 2012-06-21
==================
* Use encode/decodeURIComponent for cookie encoding/decoding
- Improve server/client interoperability
0.0.3 / 2012-06-06
==================
* Only escape special characters per the cookie RFC
0.0.2 / 2012-06-01
==================
* Fix `maxAge` option to not throw error
0.0.1 / 2012-05-28
==================
* Add more tests
0.0.0 / 2012-05-28
==================
* Initial release

24
node_modules/cookie-parser/node_modules/cookie/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,24 @@
(The MIT License)
Copyright (c) 2012-2014 Roman Shtylman <shtylman@gmail.com>
Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
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.

View File

@@ -0,0 +1,257 @@
# cookie
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]
Basic HTTP cookie parser and serializer for HTTP servers.
## Installation
This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/). Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
```sh
$ npm install cookie
```
## API
```js
var cookie = require('cookie');
```
### cookie.parse(str, options)
Parse an HTTP `Cookie` header string and returning an object of all cookie name-value pairs.
The `str` argument is the string representing a `Cookie` header value and `options` is an
optional object containing additional parsing options.
```js
var cookies = cookie.parse('foo=bar; equation=E%3Dmc%5E2');
// { foo: 'bar', equation: 'E=mc^2' }
```
#### Options
`cookie.parse` accepts these properties in the options object.
##### decode
Specifies a function that will be used to decode a cookie's value. Since the value of a cookie
has a limited character set (and must be a simple string), this function can be used to decode
a previously-encoded cookie value into a JavaScript string or other object.
The default function is the global `decodeURIComponent`, which will decode any URL-encoded
sequences into their byte representations.
**note** if an error is thrown from this function, the original, non-decoded cookie value will
be returned as the cookie's value.
### cookie.serialize(name, value, options)
Serialize a cookie name-value pair into a `Set-Cookie` header string. The `name` argument is the
name for the cookie, the `value` argument is the value to set the cookie to, and the `options`
argument is an optional object containing additional serialization options.
```js
var setCookie = cookie.serialize('foo', 'bar');
// foo=bar
```
#### Options
`cookie.serialize` accepts these properties in the options object.
##### domain
Specifies the value for the [`Domain` `Set-Cookie` attribute][rfc-6265-5.2.3]. By default, no
domain is set, and most clients will consider the cookie to apply to only the current domain.
##### encode
Specifies a function that will be used to encode a cookie's value. Since value of a cookie
has a limited character set (and must be a simple string), this function can be used to encode
a value into a string suited for a cookie's value.
The default function is the global `encodeURIComponent`, which will encode a JavaScript string
into UTF-8 byte sequences and then URL-encode any that fall outside of the cookie range.
##### expires
Specifies the `Date` object to be the value for the [`Expires` `Set-Cookie` attribute][rfc-6265-5.2.1].
By default, no expiration is set, and most clients will consider this a "non-persistent cookie" and
will delete it on a condition like exiting a web browser application.
**note** the [cookie storage model specification][rfc-6265-5.3] states that if both `expires` and
`maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this,
so if both are set, they should point to the same date and time.
##### httpOnly
Specifies the `boolean` value for the [`HttpOnly` `Set-Cookie` attribute][rfc-6265-5.2.6]. When truthy,
the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly` attribute is not set.
**note** be careful when setting this to `true`, as compliant clients will not allow client-side
JavaScript to see the cookie in `document.cookie`.
##### maxAge
Specifies the `number` (in seconds) to be the value for the [`Max-Age` `Set-Cookie` attribute][rfc-6265-5.2.2].
The given number will be converted to an integer by rounding down. By default, no maximum age is set.
**note** the [cookie storage model specification][rfc-6265-5.3] states that if both `expires` and
`maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this,
so if both are set, they should point to the same date and time.
##### path
Specifies the value for the [`Path` `Set-Cookie` attribute][rfc-6265-5.2.4]. By default, the path
is considered the ["default path"][rfc-6265-5.1.4].
##### sameSite
Specifies the `boolean` or `string` to be the value for the [`SameSite` `Set-Cookie` attribute][rfc-6265bis-03-4.1.2.7].
- `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
- `false` will not set the `SameSite` attribute.
- `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
- `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
- `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
More information about the different enforcement levels can be found in
[the specification][rfc-6265bis-03-4.1.2.7].
**note** This is an attribute that has not yet been fully standardized, and may change in the future.
This also means many clients may ignore this attribute until they understand it.
##### secure
Specifies the `boolean` value for the [`Secure` `Set-Cookie` attribute][rfc-6265-5.2.5]. When truthy,
the `Secure` attribute is set, otherwise it is not. By default, the `Secure` attribute is not set.
**note** be careful when setting this to `true`, as compliant clients will not send the cookie back to
the server in the future if the browser does not have an HTTPS connection.
## Example
The following example uses this module in conjunction with the Node.js core HTTP server
to prompt a user for their name and display it back on future visits.
```js
var cookie = require('cookie');
var escapeHtml = require('escape-html');
var http = require('http');
var url = require('url');
function onRequest(req, res) {
// Parse the query string
var query = url.parse(req.url, true, true).query;
if (query && query.name) {
// Set a new cookie with the name
res.setHeader('Set-Cookie', cookie.serialize('name', String(query.name), {
httpOnly: true,
maxAge: 60 * 60 * 24 * 7 // 1 week
}));
// Redirect back after setting cookie
res.statusCode = 302;
res.setHeader('Location', req.headers.referer || '/');
res.end();
return;
}
// Parse the cookies on the request
var cookies = cookie.parse(req.headers.cookie || '');
// Get the visitor name set in the cookie
var name = cookies.name;
res.setHeader('Content-Type', 'text/html; charset=UTF-8');
if (name) {
res.write('<p>Welcome back, <b>' + escapeHtml(name) + '</b>!</p>');
} else {
res.write('<p>Hello, new visitor!</p>');
}
res.write('<form method="GET">');
res.write('<input placeholder="enter your name" name="name"> <input type="submit" value="Set Name">');
res.end('</form>');
}
http.createServer(onRequest).listen(3000);
```
## Testing
```sh
$ npm test
```
## Benchmark
```
$ npm run bench
> cookie@0.3.1 bench cookie
> node benchmark/index.js
http_parser@2.8.0
node@6.14.2
v8@5.1.281.111
uv@1.16.1
zlib@1.2.11
ares@1.10.1-DEV
icu@58.2
modules@48
napi@3
openssl@1.0.2o
> node benchmark/parse.js
cookie.parse
6 tests completed.
simple x 1,200,691 ops/sec ±1.12% (189 runs sampled)
decode x 1,012,994 ops/sec ±0.97% (186 runs sampled)
unquote x 1,074,174 ops/sec ±2.43% (186 runs sampled)
duplicates x 438,424 ops/sec ±2.17% (184 runs sampled)
10 cookies x 147,154 ops/sec ±1.01% (186 runs sampled)
100 cookies x 14,274 ops/sec ±1.07% (187 runs sampled)
```
## References
- [RFC 6265: HTTP State Management Mechanism][rfc-6265]
- [Same-site Cookies][rfc-6265bis-03-4.1.2.7]
[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7
[rfc-6265]: https://tools.ietf.org/html/rfc6265
[rfc-6265-5.1.4]: https://tools.ietf.org/html/rfc6265#section-5.1.4
[rfc-6265-5.2.1]: https://tools.ietf.org/html/rfc6265#section-5.2.1
[rfc-6265-5.2.2]: https://tools.ietf.org/html/rfc6265#section-5.2.2
[rfc-6265-5.2.3]: https://tools.ietf.org/html/rfc6265#section-5.2.3
[rfc-6265-5.2.4]: https://tools.ietf.org/html/rfc6265#section-5.2.4
[rfc-6265-5.2.5]: https://tools.ietf.org/html/rfc6265#section-5.2.5
[rfc-6265-5.2.6]: https://tools.ietf.org/html/rfc6265#section-5.2.6
[rfc-6265-5.3]: https://tools.ietf.org/html/rfc6265#section-5.3
## License
[MIT](LICENSE)
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/cookie/master
[coveralls-url]: https://coveralls.io/r/jshttp/cookie?branch=master
[node-version-image]: https://badgen.net/npm/node/cookie
[node-version-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/cookie
[npm-url]: https://npmjs.org/package/cookie
[npm-version-image]: https://badgen.net/npm/v/cookie
[travis-image]: https://badgen.net/travis/jshttp/cookie/master
[travis-url]: https://travis-ci.org/jshttp/cookie

202
node_modules/cookie-parser/node_modules/cookie/index.js generated vendored Normal file
View File

@@ -0,0 +1,202 @@
/*!
* cookie
* Copyright(c) 2012-2014 Roman Shtylman
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
exports.parse = parse;
exports.serialize = serialize;
/**
* Module variables.
* @private
*/
var decode = decodeURIComponent;
var encode = encodeURIComponent;
var pairSplitRegExp = /; */;
/**
* RegExp to match field-content in RFC 7230 sec 3.2
*
* field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
* field-vchar = VCHAR / obs-text
* obs-text = %x80-FF
*/
var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
/**
* Parse a cookie header.
*
* Parse the given cookie header string into an object
* The object has the various cookies as keys(names) => values
*
* @param {string} str
* @param {object} [options]
* @return {object}
* @public
*/
function parse(str, options) {
if (typeof str !== 'string') {
throw new TypeError('argument str must be a string');
}
var obj = {}
var opt = options || {};
var pairs = str.split(pairSplitRegExp);
var dec = opt.decode || decode;
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i];
var eq_idx = pair.indexOf('=');
// skip things that don't look like key=value
if (eq_idx < 0) {
continue;
}
var key = pair.substr(0, eq_idx).trim()
var val = pair.substr(++eq_idx, pair.length).trim();
// quoted values
if ('"' == val[0]) {
val = val.slice(1, -1);
}
// only assign once
if (undefined == obj[key]) {
obj[key] = tryDecode(val, dec);
}
}
return obj;
}
/**
* Serialize data into a cookie header.
*
* Serialize the a name value pair into a cookie string suitable for
* http headers. An optional options object specified cookie parameters.
*
* serialize('foo', 'bar', { httpOnly: true })
* => "foo=bar; httpOnly"
*
* @param {string} name
* @param {string} val
* @param {object} [options]
* @return {string}
* @public
*/
function serialize(name, val, options) {
var opt = options || {};
var enc = opt.encode || encode;
if (typeof enc !== 'function') {
throw new TypeError('option encode is invalid');
}
if (!fieldContentRegExp.test(name)) {
throw new TypeError('argument name is invalid');
}
var value = enc(val);
if (value && !fieldContentRegExp.test(value)) {
throw new TypeError('argument val is invalid');
}
var str = name + '=' + value;
if (null != opt.maxAge) {
var maxAge = opt.maxAge - 0;
if (isNaN(maxAge) || !isFinite(maxAge)) {
throw new TypeError('option maxAge is invalid')
}
str += '; Max-Age=' + Math.floor(maxAge);
}
if (opt.domain) {
if (!fieldContentRegExp.test(opt.domain)) {
throw new TypeError('option domain is invalid');
}
str += '; Domain=' + opt.domain;
}
if (opt.path) {
if (!fieldContentRegExp.test(opt.path)) {
throw new TypeError('option path is invalid');
}
str += '; Path=' + opt.path;
}
if (opt.expires) {
if (typeof opt.expires.toUTCString !== 'function') {
throw new TypeError('option expires is invalid');
}
str += '; Expires=' + opt.expires.toUTCString();
}
if (opt.httpOnly) {
str += '; HttpOnly';
}
if (opt.secure) {
str += '; Secure';
}
if (opt.sameSite) {
var sameSite = typeof opt.sameSite === 'string'
? opt.sameSite.toLowerCase() : opt.sameSite;
switch (sameSite) {
case true:
str += '; SameSite=Strict';
break;
case 'lax':
str += '; SameSite=Lax';
break;
case 'strict':
str += '; SameSite=Strict';
break;
case 'none':
str += '; SameSite=None';
break;
default:
throw new TypeError('option sameSite is invalid');
}
}
return str;
}
/**
* Try decoding a string using a decoding function.
*
* @param {string} str
* @param {function} decode
* @private
*/
function tryDecode(str, decode) {
try {
return decode(str);
} catch (e) {
return str;
}
}

View File

@@ -0,0 +1,40 @@
{
"name": "cookie",
"description": "HTTP server cookie parsing and serialization",
"version": "0.4.1",
"author": "Roman Shtylman <shtylman@gmail.com>",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>"
],
"license": "MIT",
"keywords": [
"cookie",
"cookies"
],
"repository": "jshttp/cookie",
"devDependencies": {
"beautify-benchmark": "0.2.4",
"benchmark": "2.1.4",
"eslint": "6.8.0",
"eslint-plugin-markdown": "1.0.2",
"mocha": "7.1.1",
"nyc": "15.0.1"
},
"files": [
"HISTORY.md",
"LICENSE",
"README.md",
"index.js"
],
"engines": {
"node": ">= 0.6"
},
"scripts": {
"bench": "node benchmark/index.js",
"lint": "eslint --plugin markdown --ext js,md .",
"test": "mocha --reporter spec --bail --check-leaks --ui qunit test/",
"test-ci": "nyc --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test",
"version": "node scripts/version-history.js && git add HISTORY.md"
}
}

45
node_modules/cookie-parser/package.json generated vendored Normal file
View File

@@ -0,0 +1,45 @@
{
"name": "cookie-parser",
"description": "Parse HTTP request cookies",
"version": "1.4.6",
"author": "TJ Holowaychuk <tj@vision-media.ca> (http://tjholowaychuk.com)",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>"
],
"license": "MIT",
"repository": "expressjs/cookie-parser",
"keywords": [
"cookie",
"middleware"
],
"dependencies": {
"cookie": "0.4.1",
"cookie-signature": "1.0.6"
},
"devDependencies": {
"eslint": "7.32.0",
"eslint-config-standard": "14.1.1",
"eslint-plugin-import": "2.25.2",
"eslint-plugin-markdown": "2.2.1",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "4.3.1",
"eslint-plugin-standard": "4.1.0",
"mocha": "9.1.3",
"nyc": "15.1.0",
"supertest": "6.1.6"
},
"files": [
"LICENSE",
"HISTORY.md",
"index.js"
],
"engines": {
"node": ">= 0.8.0"
},
"scripts": {
"lint": "eslint .",
"test": "mocha --reporter spec --bail --check-leaks test/",
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test"
}
}

442
node_modules/express-session/HISTORY.md generated vendored Normal file
View File

@@ -0,0 +1,442 @@
1.17.3 / 2022-05-11
===================
* Fix resaving already-saved new session at end of request
* deps: cookie@0.4.2
1.17.2 / 2021-05-19
===================
* Fix `res.end` patch to always commit headers
* deps: cookie@0.4.1
* deps: safe-buffer@5.2.1
1.17.1 / 2020-04-16
===================
* Fix internal method wrapping error on failed reloads
1.17.0 / 2019-10-10
===================
* deps: cookie@0.4.0
- Add `SameSite=None` support
* deps: safe-buffer@5.2.0
1.16.2 / 2019-06-12
===================
* Fix restoring `cookie.originalMaxAge` when store returns `Date`
* deps: parseurl@~1.3.3
1.16.1 / 2019-04-11
===================
* Fix error passing `data` option to `Cookie` constructor
* Fix uncaught error from bad session data
1.16.0 / 2019-04-10
===================
* Catch invalid `cookie.maxAge` value earlier
* Deprecate setting `cookie.maxAge` to a `Date` object
* Fix issue where `resave: false` may not save altered sessions
* Remove `utils-merge` dependency
* Use `safe-buffer` for improved Buffer API
* Use `Set-Cookie` as cookie header name for compatibility
* deps: depd@~2.0.0
- Replace internal `eval` usage with `Function` constructor
- Use instance methods on `process` to check for listeners
- perf: remove argument reassignment
* deps: on-headers@~1.0.2
- Fix `res.writeHead` patch missing return value
1.15.6 / 2017-09-26
===================
* deps: debug@2.6.9
* deps: parseurl@~1.3.2
- perf: reduce overhead for full URLs
- perf: unroll the "fast-path" `RegExp`
* deps: uid-safe@~2.1.5
- perf: remove only trailing `=`
* deps: utils-merge@1.0.1
1.15.5 / 2017-08-02
===================
* Fix `TypeError` when `req.url` is an empty string
* deps: depd@~1.1.1
- Remove unnecessary `Buffer` loading
1.15.4 / 2017-07-18
===================
* deps: debug@2.6.8
1.15.3 / 2017-05-17
===================
* deps: debug@2.6.7
- deps: ms@2.0.0
1.15.2 / 2017-03-26
===================
* deps: debug@2.6.3
- Fix `DEBUG_MAX_ARRAY_LENGTH`
* deps: uid-safe@~2.1.4
- Remove `base64-url` dependency
1.15.1 / 2017-02-10
===================
* deps: debug@2.6.1
- Fix deprecation messages in WebStorm and other editors
- Undeprecate `DEBUG_FD` set to `1` or `2`
1.15.0 / 2017-01-22
===================
* Fix detecting modified session when session contains "cookie" property
* Fix resaving already-saved reloaded session at end of request
* deps: crc@3.4.4
- perf: use `Buffer.from` when available
* deps: debug@2.6.0
- Allow colors in workers
- Deprecated `DEBUG_FD` environment variable
- Use same color for same namespace
- Fix error when running under React Native
- deps: ms@0.7.2
* perf: remove unreachable branch in set-cookie method
1.14.2 / 2016-10-30
===================
* deps: crc@3.4.1
- Fix deprecation warning in Node.js 7.x
* deps: uid-safe@~2.1.3
- deps: base64-url@1.3.3
1.14.1 / 2016-08-24
===================
* Fix not always resetting session max age before session save
* Fix the cookie `sameSite` option to actually alter the `Set-Cookie`
* deps: uid-safe@~2.1.2
- deps: base64-url@1.3.2
1.14.0 / 2016-07-01
===================
* Correctly inherit from `EventEmitter` class in `Store` base class
* Fix issue where `Set-Cookie` `Expires` was not always updated
* Methods are no longer enumerable on `req.session` object
* deps: cookie@0.3.1
- Add `sameSite` option
- Improve error message when `encode` is not a function
- Improve error message when `expires` is not a `Date`
- perf: enable strict mode
- perf: use for loop in parse
- perf: use string concatination for serialization
* deps: parseurl@~1.3.1
- perf: enable strict mode
* deps: uid-safe@~2.1.1
- Use `random-bytes` for byte source
- deps: base64-url@1.2.2
* perf: enable strict mode
* perf: remove argument reassignment
1.13.0 / 2016-01-10
===================
* Fix `rolling: true` to not set cookie when no session exists
- Better `saveUninitialized: false` + `rolling: true` behavior
* deps: crc@3.4.0
1.12.1 / 2015-10-29
===================
* deps: cookie@0.2.3
- Fix cookie `Max-Age` to never be a floating point number
1.12.0 / 2015-10-25
===================
* Support the value `'auto'` in the `cookie.secure` option
* deps: cookie@0.2.2
- Throw on invalid values provided to `serialize`
* deps: depd@~1.1.0
- Enable strict mode in more places
- Support web browser loading
* deps: on-headers@~1.0.1
- perf: enable strict mode
1.11.3 / 2015-05-22
===================
* deps: cookie@0.1.3
- Slight optimizations
* deps: crc@3.3.0
1.11.2 / 2015-05-10
===================
* deps: debug@~2.2.0
- deps: ms@0.7.1
* deps: uid-safe@~2.0.0
1.11.1 / 2015-04-08
===================
* Fix mutating `options.secret` value
1.11.0 / 2015-04-07
===================
* Support an array in `secret` option for key rotation
* deps: depd@~1.0.1
1.10.4 / 2015-03-15
===================
* deps: debug@~2.1.3
- Fix high intensity foreground color for bold
- deps: ms@0.7.0
1.10.3 / 2015-02-16
===================
* deps: cookie-signature@1.0.6
* deps: uid-safe@1.1.0
- Use `crypto.randomBytes`, if available
- deps: base64-url@1.2.1
1.10.2 / 2015-01-31
===================
* deps: uid-safe@1.0.3
- Fix error branch that would throw
- deps: base64-url@1.2.0
1.10.1 / 2015-01-08
===================
* deps: uid-safe@1.0.2
- Remove dependency on `mz`
1.10.0 / 2015-01-05
===================
* Add `store.touch` interface for session stores
* Fix `MemoryStore` expiration with `resave: false`
* deps: debug@~2.1.1
1.9.3 / 2014-12-02
==================
* Fix error when `req.sessionID` contains a non-string value
1.9.2 / 2014-11-22
==================
* deps: crc@3.2.1
- Minor fixes
1.9.1 / 2014-10-22
==================
* Remove unnecessary empty write call
- Fixes Node.js 0.11.14 behavior change
- Helps work-around Node.js 0.10.1 zlib bug
1.9.0 / 2014-09-16
==================
* deps: debug@~2.1.0
- Implement `DEBUG_FD` env variable support
* deps: depd@~1.0.0
1.8.2 / 2014-09-15
==================
* Use `crc` instead of `buffer-crc32` for speed
* deps: depd@0.4.5
1.8.1 / 2014-09-08
==================
* Keep `req.session.save` non-enumerable
* Prevent session prototype methods from being overwritten
1.8.0 / 2014-09-07
==================
* Do not resave already-saved session at end of request
* deps: cookie-signature@1.0.5
* deps: debug@~2.0.0
1.7.6 / 2014-08-18
==================
* Fix exception on `res.end(null)` calls
1.7.5 / 2014-08-10
==================
* Fix parsing original URL
* deps: on-headers@~1.0.0
* deps: parseurl@~1.3.0
1.7.4 / 2014-08-05
==================
* Fix response end delay for non-chunked responses
1.7.3 / 2014-08-05
==================
* Fix `res.end` patch to call correct upstream `res.write`
1.7.2 / 2014-07-27
==================
* deps: depd@0.4.4
- Work-around v8 generating empty stack traces
1.7.1 / 2014-07-26
==================
* deps: depd@0.4.3
- Fix exception when global `Error.stackTraceLimit` is too low
1.7.0 / 2014-07-22
==================
* Improve session-ending error handling
- Errors are passed to `next(err)` instead of `console.error`
* deps: debug@1.0.4
* deps: depd@0.4.2
- Add `TRACE_DEPRECATION` environment variable
- Remove non-standard grey color from color output
- Support `--no-deprecation` argument
- Support `--trace-deprecation` argument
1.6.5 / 2014-07-11
==================
* Do not require `req.originalUrl`
* deps: debug@1.0.3
- Add support for multiple wildcards in namespaces
1.6.4 / 2014-07-07
==================
* Fix blank responses for stores with synchronous operations
1.6.3 / 2014-07-04
==================
* Fix resave deprecation message
1.6.2 / 2014-07-04
==================
* Fix confusing option deprecation messages
1.6.1 / 2014-06-28
==================
* Fix saveUninitialized deprecation message
1.6.0 / 2014-06-28
==================
* Add deprecation message to undefined `resave` option
* Add deprecation message to undefined `saveUninitialized` option
* Fix `res.end` patch to return correct value
* Fix `res.end` patch to handle multiple `res.end` calls
* Reject cookies with missing signatures
1.5.2 / 2014-06-26
==================
* deps: cookie-signature@1.0.4
- fix for timing attacks
1.5.1 / 2014-06-21
==================
* Move hard-to-track-down `req.secret` deprecation message
1.5.0 / 2014-06-19
==================
* Debug name is now "express-session"
* Deprecate integration with `cookie-parser` middleware
* Deprecate looking for secret in `req.secret`
* Directly read cookies; `cookie-parser` no longer required
* Directly set cookies; `res.cookie` no longer required
* Generate session IDs with `uid-safe`, faster and even less collisions
1.4.0 / 2014-06-17
==================
* Add `genid` option to generate custom session IDs
* Add `saveUninitialized` option to control saving uninitialized sessions
* Add `unset` option to control unsetting `req.session`
* Generate session IDs with `rand-token` by default; reduce collisions
* deps: buffer-crc32@0.2.3
1.3.1 / 2014-06-14
==================
* Add description in package for npmjs.org listing
1.3.0 / 2014-06-14
==================
* Integrate with express "trust proxy" by default
* deps: debug@1.0.2
1.2.1 / 2014-05-27
==================
* Fix `resave` such that `resave: true` works
1.2.0 / 2014-05-19
==================
* Add `resave` option to control saving unmodified sessions
1.1.0 / 2014-05-12
==================
* Add `name` option; replacement for `key` option
* Use `setImmediate` in MemoryStore for node.js >= 0.10
1.0.4 / 2014-04-27
==================
* deps: debug@0.8.1
1.0.3 / 2014-04-19
==================
* Use `res.cookie()` instead of `res.setHeader()`
* deps: cookie@0.1.2
1.0.2 / 2014-02-23
==================
* Add missing dependency to `package.json`
1.0.1 / 2014-02-15
==================
* Add missing dependencies to `package.json`
1.0.0 / 2014-02-15
==================
* Genesis from `connect`

24
node_modules/express-session/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,24 @@
(The MIT License)
Copyright (c) 2010 Sencha Inc.
Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>
Copyright (c) 2014-2015 Douglas Christopher Wilson <doug@somethingdoug.com>
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.

985
node_modules/express-session/README.md generated vendored Normal file
View File

@@ -0,0 +1,985 @@
# express-session
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][node-url]
[![Build Status][ci-image]][ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]
## Installation
This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/). Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
```sh
$ npm install express-session
```
## API
```js
var session = require('express-session')
```
### session(options)
Create a session middleware with the given `options`.
**Note** Session data is _not_ saved in the cookie itself, just the session ID.
Session data is stored server-side.
**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser)
no longer needs to be used for this module to work. This module now directly reads
and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues
if the `secret` is not the same between this module and `cookie-parser`.
**Warning** The default server-side session storage, `MemoryStore`, is _purposely_
not designed for a production environment. It will leak memory under most
conditions, does not scale past a single process, and is meant for debugging and
developing.
For a list of stores, see [compatible session stores](#compatible-session-stores).
#### Options
`express-session` accepts these properties in the options object.
##### cookie
Settings object for the session ID cookie. The default value is
`{ path: '/', httpOnly: true, secure: false, maxAge: null }`.
The following are options that can be set in this object.
##### cookie.domain
Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain
is set, and most clients will consider the cookie to apply to only the current
domain.
##### cookie.expires
Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute.
By default, no expiration is set, and most clients will consider this a
"non-persistent cookie" and will delete it on a condition like exiting a web browser
application.
**Note** If both `expires` and `maxAge` are set in the options, then the last one
defined in the object is what is used.
**Note** The `expires` option should not be set directly; instead only use the `maxAge`
option.
##### cookie.httpOnly
Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy,
the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly`
attribute is set.
**Note** be careful when setting this to `true`, as compliant clients will not allow
client-side JavaScript to see the cookie in `document.cookie`.
##### cookie.maxAge
Specifies the `number` (in milliseconds) to use when calculating the `Expires`
`Set-Cookie` attribute. This is done by taking the current server time and adding
`maxAge` milliseconds to the value to calculate an `Expires` datetime. By default,
no maximum age is set.
**Note** If both `expires` and `maxAge` are set in the options, then the last one
defined in the object is what is used.
##### cookie.path
Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which
is the root path of the domain.
##### cookie.sameSite
Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute.
By default, this is `false`.
- `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
- `false` will not set the `SameSite` attribute.
- `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
- `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
- `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
More information about the different enforcement levels can be found in
[the specification][rfc-6265bis-03-4.1.2.7].
**Note** This is an attribute that has not yet been fully standardized, and may change in
the future. This also means many clients may ignore this attribute until they understand it.
**Note** There is a [draft spec](https://tools.ietf.org/html/draft-west-cookie-incrementalism-01)
that requires that the `Secure` attribute be set to `true` when the `SameSite` attribute has been
set to `'none'`. Some web browsers or other clients may be adopting this specification.
##### cookie.secure
Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy,
the `Secure` attribute is set, otherwise it is not. By default, the `Secure`
attribute is not set.
**Note** be careful when setting this to `true`, as compliant clients will not send
the cookie back to the server in the future if the browser does not have an HTTPS
connection.
Please note that `secure: true` is a **recommended** option. However, it requires
an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure`
is set, and you access your site over HTTP, the cookie will not be set. If you
have your node.js behind a proxy and are using `secure: true`, you need to set
"trust proxy" in express:
```js
var app = express()
app.set('trust proxy', 1) // trust first proxy
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}))
```
For using secure cookies in production, but allowing for testing in development,
the following is an example of enabling this setup based on `NODE_ENV` in express:
```js
var app = express()
var sess = {
secret: 'keyboard cat',
cookie: {}
}
if (app.get('env') === 'production') {
app.set('trust proxy', 1) // trust first proxy
sess.cookie.secure = true // serve secure cookies
}
app.use(session(sess))
```
The `cookie.secure` option can also be set to the special value `'auto'` to have
this setting automatically match the determined security of the connection. Be
careful when using this setting if the site is available both as HTTP and HTTPS,
as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This
is useful when the Express `"trust proxy"` setting is properly setup to simplify
development vs production configuration.
##### genid
Function to call to generate a new session ID. Provide a function that returns
a string that will be used as a session ID. The function is given `req` as the
first argument if you want to use some value attached to `req` when generating
the ID.
The default value is a function which uses the `uid-safe` library to generate IDs.
**NOTE** be careful to generate unique IDs so your sessions do not conflict.
```js
app.use(session({
genid: function(req) {
return genuuid() // use UUIDs for session IDs
},
secret: 'keyboard cat'
}))
```
##### name
The name of the session ID cookie to set in the response (and read from in the
request).
The default value is `'connect.sid'`.
**Note** if you have multiple apps running on the same hostname (this is just
the name, i.e. `localhost` or `127.0.0.1`; different schemes and ports do not
name a different hostname), then you need to separate the session cookies from
each other. The simplest method is to simply set different `name`s per app.
##### proxy
Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto"
header).
The default value is `undefined`.
- `true` The "X-Forwarded-Proto" header will be used.
- `false` All headers are ignored and the connection is considered secure only
if there is a direct TLS/SSL connection.
- `undefined` Uses the "trust proxy" setting from express
##### resave
Forces the session to be saved back to the session store, even if the session
was never modified during the request. Depending on your store this may be
necessary, but it can also create race conditions where a client makes two
parallel requests to your server and changes made to the session in one
request may get overwritten when the other request ends, even if it made no
changes (this behavior also depends on what store you're using).
The default value is `true`, but using the default has been deprecated,
as the default will change in the future. Please research into this setting
and choose what is appropriate to your use-case. Typically, you'll want
`false`.
How do I know if this is necessary for my store? The best way to know is to
check with your store if it implements the `touch` method. If it does, then
you can safely set `resave: false`. If it does not implement the `touch`
method and your store sets an expiration date on stored sessions, then you
likely need `resave: true`.
##### rolling
Force the session identifier cookie to be set on every response. The expiration
is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration
countdown.
The default value is `false`.
With this enabled, the session identifier cookie will expire in
[`maxAge`](#cookiemaxage) since the last response was sent instead of in
[`maxAge`](#cookiemaxage) since the session was last modified by the server.
This is typically used in conjuction with short, non-session-length
[`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data
with reduced potential of it occurring during on going server interactions.
**Note** When this option is set to `true` but the `saveUninitialized` option is
set to `false`, the cookie will not be set on a response with an uninitialized
session. This option only modifies the behavior when an existing session was
loaded for the request.
##### saveUninitialized
Forces a session that is "uninitialized" to be saved to the store. A session is
uninitialized when it is new but not modified. Choosing `false` is useful for
implementing login sessions, reducing server storage usage, or complying with
laws that require permission before setting a cookie. Choosing `false` will also
help with race conditions where a client makes multiple parallel requests
without a session.
The default value is `true`, but using the default has been deprecated, as the
default will change in the future. Please research into this setting and
choose what is appropriate to your use-case.
**Note** if you are using Session in conjunction with PassportJS, Passport
will add an empty Passport object to the session for use after a user is
authenticated, which will be treated as a modification to the session, causing
it to be saved. *This has been fixed in PassportJS 0.3.0*
##### secret
**Required option**
This is the secret used to sign the session ID cookie. This can be either a string
for a single secret, or an array of multiple secrets. If an array of secrets is
provided, only the first element will be used to sign the session ID cookie, while
all the elements will be considered when verifying the signature in requests. The
secret itself should be not easily parsed by a human and would best be a random set
of characters. A best practice may include:
- The use of environment variables to store the secret, ensuring the secret itself
does not exist in your repository.
- Periodic updates of the secret, while ensuring the previous secret is in the
array.
Using a secret that cannot be guessed will reduce the ability to hijack a session to
only guessing the session ID (as determined by the `genid` option).
Changing the secret value will invalidate all existing sessions. In order to rotate
the secret without invalidating sessions, provide an array of secrets, with the new
secret as first element of the array, and including previous secrets as the later
elements.
##### store
The session store instance, defaults to a new `MemoryStore` instance.
##### unset
Control the result of unsetting `req.session` (through `delete`, setting to `null`,
etc.).
The default value is `'keep'`.
- `'destroy'` The session will be destroyed (deleted) when the response ends.
- `'keep'` The session in the store will be kept, but modifications made during
the request are ignored and not saved.
### req.session
To store or access session data, simply use the request property `req.session`,
which is (generally) serialized as JSON by the store, so nested objects
are typically fine. For example below is a user-specific view counter:
```js
// Use the session middleware
app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))
// Access the session as req.session
app.get('/', function(req, res, next) {
if (req.session.views) {
req.session.views++
res.setHeader('Content-Type', 'text/html')
res.write('<p>views: ' + req.session.views + '</p>')
res.write('<p>expires in: ' + (req.session.cookie.maxAge / 1000) + 's</p>')
res.end()
} else {
req.session.views = 1
res.end('welcome to the session demo. refresh!')
}
})
```
#### Session.regenerate(callback)
To regenerate the session simply invoke the method. Once complete,
a new SID and `Session` instance will be initialized at `req.session`
and the `callback` will be invoked.
```js
req.session.regenerate(function(err) {
// will have a new session here
})
```
#### Session.destroy(callback)
Destroys the session and will unset the `req.session` property.
Once complete, the `callback` will be invoked.
```js
req.session.destroy(function(err) {
// cannot access session here
})
```
#### Session.reload(callback)
Reloads the session data from the store and re-populates the
`req.session` object. Once complete, the `callback` will be invoked.
```js
req.session.reload(function(err) {
// session updated
})
```
#### Session.save(callback)
Save the session back to the store, replacing the contents on the store with the
contents in memory (though a store may do something else--consult the store's
documentation for exact behavior).
This method is automatically called at the end of the HTTP response if the
session data has been altered (though this behavior can be altered with various
options in the middleware constructor). Because of this, typically this method
does not need to be called.
There are some cases where it is useful to call this method, for example,
redirects, long-lived requests or in WebSockets.
```js
req.session.save(function(err) {
// session saved
})
```
#### Session.touch()
Updates the `.maxAge` property. Typically this is
not necessary to call, as the session middleware does this for you.
### req.session.id
Each session has a unique ID associated with it. This property is an
alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified.
It has been added to make the session ID accessible from the `session`
object.
### req.session.cookie
Each session has a unique cookie object accompany it. This allows
you to alter the session cookie per visitor. For example we can
set `req.session.cookie.expires` to `false` to enable the cookie
to remain for only the duration of the user-agent.
#### Cookie.maxAge
Alternatively `req.session.cookie.maxAge` will return the time
remaining in milliseconds, which we may also re-assign a new value
to adjust the `.expires` property appropriately. The following
are essentially equivalent
```js
var hour = 3600000
req.session.cookie.expires = new Date(Date.now() + hour)
req.session.cookie.maxAge = hour
```
For example when `maxAge` is set to `60000` (one minute), and 30 seconds
has elapsed it will return `30000` until the current request has completed,
at which time `req.session.touch()` is called to reset
`req.session.cookie.maxAge` to its original value.
```js
req.session.cookie.maxAge // => 30000
```
#### Cookie.originalMaxAge
The `req.session.cookie.originalMaxAge` property returns the original
`maxAge` (time-to-live), in milliseconds, of the session cookie.
### req.sessionID
To get the ID of the loaded session, access the request property
`req.sessionID`. This is simply a read-only value set when a session
is loaded/created.
## Session Store Implementation
Every session store _must_ be an `EventEmitter` and implement specific
methods. The following methods are the list of **required**, **recommended**,
and **optional**.
* Required methods are ones that this module will always call on the store.
* Recommended methods are ones that this module will call on the store if
available.
* Optional methods are ones this module does not call at all, but helps
present uniform stores to users.
For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
### store.all(callback)
**Optional**
This optional method is used to get all sessions in the store as an array. The
`callback` should be called as `callback(error, sessions)`.
### store.destroy(sid, callback)
**Required**
This required method is used to destroy/delete a session from the store given
a session ID (`sid`). The `callback` should be called as `callback(error)` once
the session is destroyed.
### store.clear(callback)
**Optional**
This optional method is used to delete all sessions from the store. The
`callback` should be called as `callback(error)` once the store is cleared.
### store.length(callback)
**Optional**
This optional method is used to get the count of all sessions in the store.
The `callback` should be called as `callback(error, len)`.
### store.get(sid, callback)
**Required**
This required method is used to get a session from the store given a session
ID (`sid`). The `callback` should be called as `callback(error, session)`.
The `session` argument should be a session if found, otherwise `null` or
`undefined` if the session was not found (and there was no error). A special
case is made when `error.code === 'ENOENT'` to act like `callback(null, null)`.
### store.set(sid, session, callback)
**Required**
This required method is used to upsert a session into the store given a
session ID (`sid`) and session (`session`) object. The callback should be
called as `callback(error)` once the session has been set in the store.
### store.touch(sid, session, callback)
**Recommended**
This recommended method is used to "touch" a given session given a
session ID (`sid`) and session (`session`) object. The `callback` should be
called as `callback(error)` once the session has been touched.
This is primarily used when the store will automatically delete idle sessions
and this method is used to signal to the store the given session is active,
potentially resetting the idle timer.
## Compatible Session Stores
The following modules implement a session store that is compatible with this
module. Please make a PR to add additional modules :)
[![★][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] A session store using [Aerospike](http://www.aerospike.com/).
[aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store
[aerospike-session-store-image]: https://badgen.net/github/stars/aerospike/aerospike-session-store-expressjs?label=%E2%98%85
[![★][better-sqlite3-session-store-image] better-sqlite3-session-store][better-sqlite3-session-store-url] A session store based on [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3).
[better-sqlite3-session-store-url]: https://www.npmjs.com/package/better-sqlite3-session-store
[better-sqlite3-session-store-image]: https://badgen.net/github/stars/timdaub/better-sqlite3-session-store?label=%E2%98%85
[![★][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store.
[cassandra-store-url]: https://www.npmjs.com/package/cassandra-store
[cassandra-store-image]: https://badgen.net/github/stars/webcc/cassandra-store?label=%E2%98%85
[![★][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded
stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2
and other multi-core embedded devices).
[cluster-store-url]: https://www.npmjs.com/package/cluster-store
[cluster-store-image]: https://badgen.net/github/stars/coolaj86/cluster-store?label=%E2%98%85
[![★][connect-arango-image] connect-arango][connect-arango-url] An ArangoDB-based session store.
[connect-arango-url]: https://www.npmjs.com/package/connect-arango
[connect-arango-image]: https://badgen.net/github/stars/AlexanderArvidsson/connect-arango?label=%E2%98%85
[![★][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store.
[connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables
[connect-azuretables-image]: https://badgen.net/github/stars/mike-goodwin/connect-azuretables?label=%E2%98%85
[![★][connect-cloudant-store-image] connect-cloudant-store][connect-cloudant-store-url] An [IBM Cloudant](https://cloudant.com/)-based session store.
[connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store
[connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85
[![★][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store.
[connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase
[connect-couchbase-image]: https://badgen.net/github/stars/christophermina/connect-couchbase?label=%E2%98%85
[![★][connect-datacache-image] connect-datacache][connect-datacache-url] An [IBM Bluemix Data Cache](http://www.ibm.com/cloud-computing/bluemix/)-based session store.
[connect-datacache-url]: https://www.npmjs.com/package/connect-datacache
[connect-datacache-image]: https://badgen.net/github/stars/adriantanasa/connect-datacache?label=%E2%98%85
[![★][@google-cloud/connect-datastore-image] @google-cloud/connect-datastore][@google-cloud/connect-datastore-url] A [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/overview)-based session store.
[@google-cloud/connect-datastore-url]: https://www.npmjs.com/package/@google-cloud/connect-datastore
[@google-cloud/connect-datastore-image]: https://badgen.net/github/stars/GoogleCloudPlatform/cloud-datastore-session-node?label=%E2%98%85
[![★][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module.
[connect-db2-url]: https://www.npmjs.com/package/connect-db2
[connect-db2-image]: https://badgen.net/github/stars/wallali/connect-db2?label=%E2%98%85
[![★][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store.
[connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb
[connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85
[![★][@google-cloud/connect-firestore-image] @google-cloud/connect-firestore][@google-cloud/connect-firestore-url] A [Google Cloud Firestore](https://cloud.google.com/firestore/docs/overview)-based session store.
[@google-cloud/connect-firestore-url]: https://www.npmjs.com/package/@google-cloud/connect-firestore
[@google-cloud/connect-firestore-image]: https://badgen.net/github/stars/googleapis/nodejs-firestore-session?label=%E2%98%85
[![★][connect-hazelcast-image] connect-hazelcast][connect-hazelcast-url] Hazelcast session store for Connect and Express.
[connect-hazelcast-url]: https://www.npmjs.com/package/connect-hazelcast
[connect-hazelcast-image]: https://badgen.net/github/stars/huseyinbabal/connect-hazelcast?label=%E2%98%85
[![★][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store.
[connect-loki-url]: https://www.npmjs.com/package/connect-loki
[connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85
[![★][connect-lowdb-image] connect-lowdb][connect-lowdb-url] A lowdb-based session store.
[connect-lowdb-url]: https://www.npmjs.com/package/connect-lowdb
[connect-lowdb-image]: https://badgen.net/github/stars/travishorn/connect-lowdb?label=%E2%98%85
[![★][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store.
[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached
[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85
[![★][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using
[memjs](https://www.npmjs.com/package/memjs) as the memcached client.
[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs
[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85
[![★][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store.
[connect-ml-url]: https://www.npmjs.com/package/connect-ml
[connect-ml-image]: https://badgen.net/github/stars/bluetorch/connect-ml?label=%E2%98%85
[![★][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store.
[connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb
[connect-monetdb-image]: https://badgen.net/github/stars/MonetDB/npm-connect-monetdb?label=%E2%98%85
[![★][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store.
[connect-mongo-url]: https://www.npmjs.com/package/connect-mongo
[connect-mongo-image]: https://badgen.net/github/stars/kcbanner/connect-mongo?label=%E2%98%85
[![★][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB.
[connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session
[connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85
[![★][connect-mssql-v2-image] connect-mssql-v2][connect-mssql-v2-url] A Microsoft SQL Server-based session store based on [connect-mssql](https://www.npmjs.com/package/connect-mssql).
[connect-mssql-v2-url]: https://www.npmjs.com/package/connect-mssql-v2
[connect-mssql-v2-image]: https://badgen.net/github/stars/jluboff/connect-mssql-v2?label=%E2%98%85
[![★][connect-neo4j-image] connect-neo4j][connect-neo4j-url] A [Neo4j](https://neo4j.com)-based session store.
[connect-neo4j-url]: https://www.npmjs.com/package/connect-neo4j
[connect-neo4j-image]: https://badgen.net/github/stars/MaxAndersson/connect-neo4j?label=%E2%98%85
[![★][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store.
[connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple
[connect-pg-simple-image]: https://badgen.net/github/stars/voxpelli/node-connect-pg-simple?label=%E2%98%85
[![★][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store.
[connect-redis-url]: https://www.npmjs.com/package/connect-redis
[connect-redis-image]: https://badgen.net/github/stars/tj/connect-redis?label=%E2%98%85
[![★][connect-session-firebase-image] connect-session-firebase][connect-session-firebase-url] A session store based on the [Firebase Realtime Database](https://firebase.google.com/docs/database/)
[connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase
[connect-session-firebase-image]: https://badgen.net/github/stars/benweier/connect-session-firebase?label=%E2%98%85
[![★][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using
[Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle.
[connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex
[connect-session-knex-image]: https://badgen.net/github/stars/llambda/connect-session-knex?label=%E2%98%85
[![★][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using
[Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL.
[connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize
[connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85
[![★][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store.
[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3
[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85
[![★][connect-typeorm-image] connect-typeorm][connect-typeorm-url] A [TypeORM](https://github.com/typeorm/typeorm)-based session store.
[connect-typeorm-url]: https://www.npmjs.com/package/connect-typeorm
[connect-typeorm-image]: https://badgen.net/github/stars/makepost/connect-typeorm?label=%E2%98%85
[![★][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store.
[couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression
[couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85
[![★][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store.
[dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store
[dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85
[![★][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store.
[express-etcd-url]: https://www.npmjs.com/package/express-etcd
[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85
[![★][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native
[MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module.
[express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session
[express-mysql-session-image]: https://badgen.net/github/stars/chill117/express-mysql-session?label=%E2%98%85
[![★][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store.
[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session
[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85
[![★][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native
[oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module.
[express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session
[express-oracle-session-image]: https://badgen.net/github/stars/slumber86/express-oracle-session?label=%E2%98%85
[![★][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url]
A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports
a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines).
[express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager
[express-session-cache-manager-image]: https://badgen.net/github/stars/theogravity/express-session-cache-manager?label=%E2%98%85
[![★][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store.
[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3
[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85
[![★][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store.
[express-session-level-url]: https://www.npmjs.com/package/express-session-level
[express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85
[![★][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerfull, flat file database.
[express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb
[express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85
[![★][express-sessions-image] express-sessions][express-sessions-url] A session store supporting both MongoDB and Redis.
[express-sessions-url]: https://www.npmjs.com/package/express-sessions
[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85
[![★][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store.
[firestore-store-url]: https://www.npmjs.com/package/firestore-store
[firestore-store-image]: https://badgen.net/github/stars/hendrysadrak/firestore-store?label=%E2%98%85
[![★][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune)
based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB).
[fortune-session-url]: https://www.npmjs.com/package/fortune-session
[fortune-session-image]: https://badgen.net/github/stars/aliceklipper/fortune-session?label=%E2%98%85
[![★][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client).
[hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store
[hazelcast-store-image]: https://badgen.net/github/stars/jackspaniel/hazelcast-store?label=%E2%98%85
[![★][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store.
[level-session-store-url]: https://www.npmjs.com/package/level-session-store
[level-session-store-image]: https://badgen.net/github/stars/toddself/level-session-store?label=%E2%98%85
[![★][lowdb-session-store-image] lowdb-session-store][lowdb-session-store-url] A [lowdb](https://www.npmjs.com/package/lowdb)-based session store.
[lowdb-session-store-url]: https://www.npmjs.com/package/lowdb-session-store
[lowdb-session-store-image]: https://badgen.net/github/stars/fhellwig/lowdb-session-store?label=%E2%98%85
[![★][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store.
[medea-session-store-url]: https://www.npmjs.com/package/medea-session-store
[medea-session-store-image]: https://badgen.net/github/stars/BenjaminVadant/medea-session-store?label=%E2%98%85
[![★][memorystore-image] memorystore][memorystore-url] A memory session store made for production.
[memorystore-url]: https://www.npmjs.com/package/memorystore
[memorystore-image]: https://badgen.net/github/stars/roccomuso/memorystore?label=%E2%98%85
[![★][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store.
[mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store
[mssql-session-store-image]: https://badgen.net/github/stars/jwathen/mssql-session-store?label=%E2%98%85
[![★][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store.
[nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store
[nedb-session-store-image]: https://badgen.net/github/stars/JamesMGreene/nedb-session-store?label=%E2%98%85
[![★][@quixo3/prisma-session-store-image] @quixo3/prisma-session-store][@quixo3/prisma-session-store-url] A session store for the [Prisma Framework](https://www.prisma.io).
[@quixo3/prisma-session-store-url]: https://www.npmjs.com/package/@quixo3/prisma-session-store
[@quixo3/prisma-session-store-image]: https://badgen.net/github/stars/kleydon/prisma-session-store?label=%E2%98%85
[![★][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API
[restsession-url]: https://www.npmjs.com/package/restsession
[restsession-image]: https://badgen.net/github/stars/jankal/restsession?label=%E2%98%85
[![★][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/).
[sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect
[sequelstore-connect-image]: https://badgen.net/github/stars/MattMcFarland/sequelstore-connect?label=%E2%98%85
[![★][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store.
[session-file-store-url]: https://www.npmjs.com/package/session-file-store
[session-file-store-image]: https://badgen.net/github/stars/valery-barysok/session-file-store?label=%E2%98%85
[![★][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] Session store for PouchDB / CouchDB. Accepts embedded, custom, or remote PouchDB instance and realtime synchronization.
[session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store
[session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85
[![★][session-rethinkdb-image] session-rethinkdb][session-rethinkdb-url] A [RethinkDB](http://rethinkdb.com/)-based session store.
[session-rethinkdb-url]: https://www.npmjs.com/package/session-rethinkdb
[session-rethinkdb-image]: https://badgen.net/github/stars/llambda/session-rethinkdb?label=%E2%98%85
[![★][@databunker/session-store-image] @databunker/session-store][@databunker/session-store-url] A [Databunker](https://databunker.org/)-based encrypted session store.
[@databunker/session-store-url]: https://www.npmjs.com/package/@databunker/session-store
[@databunker/session-store-image]: https://badgen.net/github/stars/securitybunker/databunker-session-store?label=%E2%98%85
[![★][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases.
[sessionstore-url]: https://www.npmjs.com/package/sessionstore
[sessionstore-image]: https://badgen.net/github/stars/adrai/sessionstore?label=%E2%98%85
[![★][tch-nedb-session-image] tch-nedb-session][tch-nedb-session-url] A file system session store based on NeDB.
[tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session
[tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85
## Examples
### View counter
A simple example using `express-session` to store page views for a user.
```js
var express = require('express')
var parseurl = require('parseurl')
var session = require('express-session')
var app = express()
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true
}))
app.use(function (req, res, next) {
if (!req.session.views) {
req.session.views = {}
}
// get the url pathname
var pathname = parseurl(req).pathname
// count the views
req.session.views[pathname] = (req.session.views[pathname] || 0) + 1
next()
})
app.get('/foo', function (req, res, next) {
res.send('you viewed this page ' + req.session.views['/foo'] + ' times')
})
app.get('/bar', function (req, res, next) {
res.send('you viewed this page ' + req.session.views['/bar'] + ' times')
})
app.listen(3000)
```
### User login
A simple example using `express-session` to keep a user log in session.
```js
var escapeHtml = require('escape-html')
var express = require('express')
var session = require('express-session')
var app = express()
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true
}))
// middleware to test if authenticated
function isAuthenticated (req, res, next) {
if (req.session.user) next()
else next('route')
}
app.get('/', isAuthenticated, function (req, res) {
// this is only called when there is an authentication user due to isAuthenticated
res.send('hello, ' + escapeHtml(req.session.user) + '!' +
' <a href="/logout">Logout</a>')
})
app.get('/', function (req, res) {
res.send('<form action="/login" method="post">' +
'Username: <input name="user"><br>' +
'Password: <input name="pass" type="password"><br>' +
'<input type="submit" text="Login"></form>')
})
app.post('/login', express.urlencoded({ extended: false }), function (req, res) {
// login logic to validate req.body.user and req.body.pass
// would be implemented here. for this example any combo works
// regenerate the session, which is good practice to help
// guard against forms of session fixation
req.session.regenerate(function (err) {
if (err) next(err)
// store user information in session, typically a user id
req.session.user = req.body.user
// save the session before redirection to ensure page
// load does not happen before session is saved
req.session.save(function (err) {
if (err) return next(err)
res.redirect('/')
})
})
})
app.get('/logout', function (req, res, next) {
// logout logic
// clear the user from the session object and save.
// this will ensure that re-using the old session id
// does not have a logged in user
req.session.user = null
req.session.save(function (err) {
if (err) next(err)
// regenerate the session, which is good practice to help
// guard against forms of session fixation
req.session.regenerate(function (err) {
if (err) next(err)
res.redirect('/')
})
})
})
app.listen(3000)
```
## Debugging
This module uses the [debug](https://www.npmjs.com/package/debug) module
internally to log information about session operations.
To see all the internal logs, set the `DEBUG` environment variable to
`express-session` when launching your app (`npm start`, in this example):
```sh
$ DEBUG=express-session npm start
```
On Windows, use the corresponding command;
```sh
> set DEBUG=express-session & npm start
```
## License
[MIT](LICENSE)
[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7
[ci-image]: https://badgen.net/github/checks/expressjs/session/master?label=ci
[ci-url]: https://github.com/expressjs/session/actions?query=workflow%3Aci
[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master
[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master
[node-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/express-session
[npm-url]: https://npmjs.org/package/express-session
[npm-version-image]: https://badgen.net/npm/v/express-session

685
node_modules/express-session/index.js generated vendored Normal file
View File

@@ -0,0 +1,685 @@
/*!
* express-session
* Copyright(c) 2010 Sencha Inc.
* Copyright(c) 2011 TJ Holowaychuk
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
* @private
*/
var Buffer = require('safe-buffer').Buffer
var cookie = require('cookie');
var crypto = require('crypto')
var debug = require('debug')('express-session');
var deprecate = require('depd')('express-session');
var onHeaders = require('on-headers')
var parseUrl = require('parseurl');
var signature = require('cookie-signature')
var uid = require('uid-safe').sync
var Cookie = require('./session/cookie')
var MemoryStore = require('./session/memory')
var Session = require('./session/session')
var Store = require('./session/store')
// environment
var env = process.env.NODE_ENV;
/**
* Expose the middleware.
*/
exports = module.exports = session;
/**
* Expose constructors.
*/
exports.Store = Store;
exports.Cookie = Cookie;
exports.Session = Session;
exports.MemoryStore = MemoryStore;
/**
* Warning message for `MemoryStore` usage in production.
* @private
*/
var warning = 'Warning: connect.session() MemoryStore is not\n'
+ 'designed for a production environment, as it will leak\n'
+ 'memory, and will not scale past a single process.';
/**
* Node.js 0.8+ async implementation.
* @private
*/
/* istanbul ignore next */
var defer = typeof setImmediate === 'function'
? setImmediate
: function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) }
/**
* Setup session store with the given `options`.
*
* @param {Object} [options]
* @param {Object} [options.cookie] Options for cookie
* @param {Function} [options.genid]
* @param {String} [options.name=connect.sid] Session ID cookie name
* @param {Boolean} [options.proxy]
* @param {Boolean} [options.resave] Resave unmodified sessions back to the store
* @param {Boolean} [options.rolling] Enable/disable rolling session expiration
* @param {Boolean} [options.saveUninitialized] Save uninitialized sessions to the store
* @param {String|Array} [options.secret] Secret for signing session ID
* @param {Object} [options.store=MemoryStore] Session store
* @param {String} [options.unset]
* @return {Function} middleware
* @public
*/
function session(options) {
var opts = options || {}
// get the cookie options
var cookieOptions = opts.cookie || {}
// get the session id generate function
var generateId = opts.genid || generateSessionId
// get the session cookie name
var name = opts.name || opts.key || 'connect.sid'
// get the session store
var store = opts.store || new MemoryStore()
// get the trust proxy setting
var trustProxy = opts.proxy
// get the resave session option
var resaveSession = opts.resave;
// get the rolling session option
var rollingSessions = Boolean(opts.rolling)
// get the save uninitialized session option
var saveUninitializedSession = opts.saveUninitialized
// get the cookie signing secret
var secret = opts.secret
if (typeof generateId !== 'function') {
throw new TypeError('genid option must be a function');
}
if (resaveSession === undefined) {
deprecate('undefined resave option; provide resave option');
resaveSession = true;
}
if (saveUninitializedSession === undefined) {
deprecate('undefined saveUninitialized option; provide saveUninitialized option');
saveUninitializedSession = true;
}
if (opts.unset && opts.unset !== 'destroy' && opts.unset !== 'keep') {
throw new TypeError('unset option must be "destroy" or "keep"');
}
// TODO: switch to "destroy" on next major
var unsetDestroy = opts.unset === 'destroy'
if (Array.isArray(secret) && secret.length === 0) {
throw new TypeError('secret option array must contain one or more strings');
}
if (secret && !Array.isArray(secret)) {
secret = [secret];
}
if (!secret) {
deprecate('req.secret; provide secret option');
}
// notify user that this store is not
// meant for a production environment
/* istanbul ignore next: not tested */
if (env === 'production' && store instanceof MemoryStore) {
console.warn(warning);
}
// generates the new session
store.generate = function(req){
req.sessionID = generateId(req);
req.session = new Session(req);
req.session.cookie = new Cookie(cookieOptions);
if (cookieOptions.secure === 'auto') {
req.session.cookie.secure = issecure(req, trustProxy);
}
};
var storeImplementsTouch = typeof store.touch === 'function';
// register event listeners for the store to track readiness
var storeReady = true
store.on('disconnect', function ondisconnect() {
storeReady = false
})
store.on('connect', function onconnect() {
storeReady = true
})
return function session(req, res, next) {
// self-awareness
if (req.session) {
next()
return
}
// Handle connection as if there is no session if
// the store has temporarily disconnected etc
if (!storeReady) {
debug('store is disconnected')
next()
return
}
// pathname mismatch
var originalPath = parseUrl.original(req).pathname || '/'
if (originalPath.indexOf(cookieOptions.path || '/') !== 0) return next();
// ensure a secret is available or bail
if (!secret && !req.secret) {
next(new Error('secret option required for sessions'));
return;
}
// backwards compatibility for signed cookies
// req.secret is passed from the cookie parser middleware
var secrets = secret || [req.secret];
var originalHash;
var originalId;
var savedHash;
var touched = false
// expose store
req.sessionStore = store;
// get the session ID from the cookie
var cookieId = req.sessionID = getcookie(req, name, secrets);
// set-cookie
onHeaders(res, function(){
if (!req.session) {
debug('no session');
return;
}
if (!shouldSetCookie(req)) {
return;
}
// only send secure cookies via https
if (req.session.cookie.secure && !issecure(req, trustProxy)) {
debug('not secured');
return;
}
if (!touched) {
// touch session
req.session.touch()
touched = true
}
// set cookie
setcookie(res, name, req.sessionID, secrets[0], req.session.cookie.data);
});
// proxy end() to commit the session
var _end = res.end;
var _write = res.write;
var ended = false;
res.end = function end(chunk, encoding) {
if (ended) {
return false;
}
ended = true;
var ret;
var sync = true;
function writeend() {
if (sync) {
ret = _end.call(res, chunk, encoding);
sync = false;
return;
}
_end.call(res);
}
function writetop() {
if (!sync) {
return ret;
}
if (!res._header) {
res._implicitHeader()
}
if (chunk == null) {
ret = true;
return ret;
}
var contentLength = Number(res.getHeader('Content-Length'));
if (!isNaN(contentLength) && contentLength > 0) {
// measure chunk
chunk = !Buffer.isBuffer(chunk)
? Buffer.from(chunk, encoding)
: chunk;
encoding = undefined;
if (chunk.length !== 0) {
debug('split response');
ret = _write.call(res, chunk.slice(0, chunk.length - 1));
chunk = chunk.slice(chunk.length - 1, chunk.length);
return ret;
}
}
ret = _write.call(res, chunk, encoding);
sync = false;
return ret;
}
if (shouldDestroy(req)) {
// destroy session
debug('destroying');
store.destroy(req.sessionID, function ondestroy(err) {
if (err) {
defer(next, err);
}
debug('destroyed');
writeend();
});
return writetop();
}
// no session to save
if (!req.session) {
debug('no session');
return _end.call(res, chunk, encoding);
}
if (!touched) {
// touch session
req.session.touch()
touched = true
}
if (shouldSave(req)) {
req.session.save(function onsave(err) {
if (err) {
defer(next, err);
}
writeend();
});
return writetop();
} else if (storeImplementsTouch && shouldTouch(req)) {
// store implements touch method
debug('touching');
store.touch(req.sessionID, req.session, function ontouch(err) {
if (err) {
defer(next, err);
}
debug('touched');
writeend();
});
return writetop();
}
return _end.call(res, chunk, encoding);
};
// generate the session
function generate() {
store.generate(req);
originalId = req.sessionID;
originalHash = hash(req.session);
wrapmethods(req.session);
}
// inflate the session
function inflate (req, sess) {
store.createSession(req, sess)
originalId = req.sessionID
originalHash = hash(sess)
if (!resaveSession) {
savedHash = originalHash
}
wrapmethods(req.session)
}
function rewrapmethods (sess, callback) {
return function () {
if (req.session !== sess) {
wrapmethods(req.session)
}
callback.apply(this, arguments)
}
}
// wrap session methods
function wrapmethods(sess) {
var _reload = sess.reload
var _save = sess.save;
function reload(callback) {
debug('reloading %s', this.id)
_reload.call(this, rewrapmethods(this, callback))
}
function save() {
debug('saving %s', this.id);
savedHash = hash(this);
_save.apply(this, arguments);
}
Object.defineProperty(sess, 'reload', {
configurable: true,
enumerable: false,
value: reload,
writable: true
})
Object.defineProperty(sess, 'save', {
configurable: true,
enumerable: false,
value: save,
writable: true
});
}
// check if session has been modified
function isModified(sess) {
return originalId !== sess.id || originalHash !== hash(sess);
}
// check if session has been saved
function isSaved(sess) {
return originalId === sess.id && savedHash === hash(sess);
}
// determine if session should be destroyed
function shouldDestroy(req) {
return req.sessionID && unsetDestroy && req.session == null;
}
// determine if session should be saved to store
function shouldSave(req) {
// cannot set cookie without a session ID
if (typeof req.sessionID !== 'string') {
debug('session ignored because of bogus req.sessionID %o', req.sessionID);
return false;
}
return !saveUninitializedSession && !savedHash && cookieId !== req.sessionID
? isModified(req.session)
: !isSaved(req.session)
}
// determine if session should be touched
function shouldTouch(req) {
// cannot set cookie without a session ID
if (typeof req.sessionID !== 'string') {
debug('session ignored because of bogus req.sessionID %o', req.sessionID);
return false;
}
return cookieId === req.sessionID && !shouldSave(req);
}
// determine if cookie should be set on response
function shouldSetCookie(req) {
// cannot set cookie without a session ID
if (typeof req.sessionID !== 'string') {
return false;
}
return cookieId !== req.sessionID
? saveUninitializedSession || isModified(req.session)
: rollingSessions || req.session.cookie.expires != null && isModified(req.session);
}
// generate a session if the browser doesn't send a sessionID
if (!req.sessionID) {
debug('no SID sent, generating session');
generate();
next();
return;
}
// generate the session object
debug('fetching %s', req.sessionID);
store.get(req.sessionID, function(err, sess){
// error handling
if (err && err.code !== 'ENOENT') {
debug('error %j', err);
next(err)
return
}
try {
if (err || !sess) {
debug('no session found')
generate()
} else {
debug('session found')
inflate(req, sess)
}
} catch (e) {
next(e)
return
}
next()
});
};
};
/**
* Generate a session ID for a new session.
*
* @return {String}
* @private
*/
function generateSessionId(sess) {
return uid(24);
}
/**
* Get the session ID cookie from request.
*
* @return {string}
* @private
*/
function getcookie(req, name, secrets) {
var header = req.headers.cookie;
var raw;
var val;
// read from cookie header
if (header) {
var cookies = cookie.parse(header);
raw = cookies[name];
if (raw) {
if (raw.substr(0, 2) === 's:') {
val = unsigncookie(raw.slice(2), secrets);
if (val === false) {
debug('cookie signature invalid');
val = undefined;
}
} else {
debug('cookie unsigned')
}
}
}
// back-compat read from cookieParser() signedCookies data
if (!val && req.signedCookies) {
val = req.signedCookies[name];
if (val) {
deprecate('cookie should be available in req.headers.cookie');
}
}
// back-compat read from cookieParser() cookies data
if (!val && req.cookies) {
raw = req.cookies[name];
if (raw) {
if (raw.substr(0, 2) === 's:') {
val = unsigncookie(raw.slice(2), secrets);
if (val) {
deprecate('cookie should be available in req.headers.cookie');
}
if (val === false) {
debug('cookie signature invalid');
val = undefined;
}
} else {
debug('cookie unsigned')
}
}
}
return val;
}
/**
* Hash the given `sess` object omitting changes to `.cookie`.
*
* @param {Object} sess
* @return {String}
* @private
*/
function hash(sess) {
// serialize
var str = JSON.stringify(sess, function (key, val) {
// ignore sess.cookie property
if (this === sess && key === 'cookie') {
return
}
return val
})
// hash
return crypto
.createHash('sha1')
.update(str, 'utf8')
.digest('hex')
}
/**
* Determine if request is secure.
*
* @param {Object} req
* @param {Boolean} [trustProxy]
* @return {Boolean}
* @private
*/
function issecure(req, trustProxy) {
// socket is https server
if (req.connection && req.connection.encrypted) {
return true;
}
// do not trust proxy
if (trustProxy === false) {
return false;
}
// no explicit trust; try req.secure from express
if (trustProxy !== true) {
return req.secure === true
}
// read the proto from x-forwarded-proto header
var header = req.headers['x-forwarded-proto'] || '';
var index = header.indexOf(',');
var proto = index !== -1
? header.substr(0, index).toLowerCase().trim()
: header.toLowerCase().trim()
return proto === 'https';
}
/**
* Set cookie on response.
*
* @private
*/
function setcookie(res, name, val, secret, options) {
var signed = 's:' + signature.sign(val, secret);
var data = cookie.serialize(name, signed, options);
debug('set-cookie %s', data);
var prev = res.getHeader('Set-Cookie') || []
var header = Array.isArray(prev) ? prev.concat(data) : [prev, data];
res.setHeader('Set-Cookie', header)
}
/**
* Verify and decode the given `val` with `secrets`.
*
* @param {String} val
* @param {Array} secrets
* @returns {String|Boolean}
* @private
*/
function unsigncookie(val, secrets) {
for (var i = 0; i < secrets.length; i++) {
var result = signature.unsign(val, secrets[i]);
if (result !== false) {
return result;
}
}
return false;
}

View File

@@ -0,0 +1,134 @@
0.4.2 / 2022-02-02
==================
* pref: read value only when assigning in parse
* pref: remove unnecessary regexp in parse
0.4.1 / 2020-04-21
==================
* Fix `maxAge` option to reject invalid values
0.4.0 / 2019-05-15
==================
* Add `SameSite=None` support
0.3.1 / 2016-05-26
==================
* Fix `sameSite: true` to work with draft-7 clients
- `true` now sends `SameSite=Strict` instead of `SameSite`
0.3.0 / 2016-05-26
==================
* Add `sameSite` option
- Replaces `firstPartyOnly` option, never implemented by browsers
* Improve error message when `encode` is not a function
* Improve error message when `expires` is not a `Date`
0.2.4 / 2016-05-20
==================
* perf: enable strict mode
* perf: use for loop in parse
* perf: use string concatination for serialization
0.2.3 / 2015-10-25
==================
* Fix cookie `Max-Age` to never be a floating point number
0.2.2 / 2015-09-17
==================
* Fix regression when setting empty cookie value
- Ease the new restriction, which is just basic header-level validation
* Fix typo in invalid value errors
0.2.1 / 2015-09-17
==================
* Throw on invalid values provided to `serialize`
- Ensures the resulting string is a valid HTTP header value
0.2.0 / 2015-08-13
==================
* Add `firstPartyOnly` option
* Throw better error for invalid argument to parse
* perf: hoist regular expression
0.1.5 / 2015-09-17
==================
* Fix regression when setting empty cookie value
- Ease the new restriction, which is just basic header-level validation
* Fix typo in invalid value errors
0.1.4 / 2015-09-17
==================
* Throw better error for invalid argument to parse
* Throw on invalid values provided to `serialize`
- Ensures the resulting string is a valid HTTP header value
0.1.3 / 2015-05-19
==================
* Reduce the scope of try-catch deopt
* Remove argument reassignments
0.1.2 / 2014-04-16
==================
* Remove unnecessary files from npm package
0.1.1 / 2014-02-23
==================
* Fix bad parse when cookie value contained a comma
* Fix support for `maxAge` of `0`
0.1.0 / 2013-05-01
==================
* Add `decode` option
* Add `encode` option
0.0.6 / 2013-04-08
==================
* Ignore cookie parts missing `=`
0.0.5 / 2012-10-29
==================
* Return raw cookie value if value unescape errors
0.0.4 / 2012-06-21
==================
* Use encode/decodeURIComponent for cookie encoding/decoding
- Improve server/client interoperability
0.0.3 / 2012-06-06
==================
* Only escape special characters per the cookie RFC
0.0.2 / 2012-06-01
==================
* Fix `maxAge` option to not throw error
0.0.1 / 2012-05-28
==================
* Add more tests
0.0.0 / 2012-05-28
==================
* Initial release

View File

@@ -0,0 +1,24 @@
(The MIT License)
Copyright (c) 2012-2014 Roman Shtylman <shtylman@gmail.com>
Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
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.

View File

@@ -0,0 +1,286 @@
# cookie
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][github-actions-ci-image]][github-actions-ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]
Basic HTTP cookie parser and serializer for HTTP servers.
## Installation
This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/). Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
```sh
$ npm install cookie
```
## API
```js
var cookie = require('cookie');
```
### cookie.parse(str, options)
Parse an HTTP `Cookie` header string and returning an object of all cookie name-value pairs.
The `str` argument is the string representing a `Cookie` header value and `options` is an
optional object containing additional parsing options.
```js
var cookies = cookie.parse('foo=bar; equation=E%3Dmc%5E2');
// { foo: 'bar', equation: 'E=mc^2' }
```
#### Options
`cookie.parse` accepts these properties in the options object.
##### decode
Specifies a function that will be used to decode a cookie's value. Since the value of a cookie
has a limited character set (and must be a simple string), this function can be used to decode
a previously-encoded cookie value into a JavaScript string or other object.
The default function is the global `decodeURIComponent`, which will decode any URL-encoded
sequences into their byte representations.
**note** if an error is thrown from this function, the original, non-decoded cookie value will
be returned as the cookie's value.
### cookie.serialize(name, value, options)
Serialize a cookie name-value pair into a `Set-Cookie` header string. The `name` argument is the
name for the cookie, the `value` argument is the value to set the cookie to, and the `options`
argument is an optional object containing additional serialization options.
```js
var setCookie = cookie.serialize('foo', 'bar');
// foo=bar
```
#### Options
`cookie.serialize` accepts these properties in the options object.
##### domain
Specifies the value for the [`Domain` `Set-Cookie` attribute][rfc-6265-5.2.3]. By default, no
domain is set, and most clients will consider the cookie to apply to only the current domain.
##### encode
Specifies a function that will be used to encode a cookie's value. Since value of a cookie
has a limited character set (and must be a simple string), this function can be used to encode
a value into a string suited for a cookie's value.
The default function is the global `encodeURIComponent`, which will encode a JavaScript string
into UTF-8 byte sequences and then URL-encode any that fall outside of the cookie range.
##### expires
Specifies the `Date` object to be the value for the [`Expires` `Set-Cookie` attribute][rfc-6265-5.2.1].
By default, no expiration is set, and most clients will consider this a "non-persistent cookie" and
will delete it on a condition like exiting a web browser application.
**note** the [cookie storage model specification][rfc-6265-5.3] states that if both `expires` and
`maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this,
so if both are set, they should point to the same date and time.
##### httpOnly
Specifies the `boolean` value for the [`HttpOnly` `Set-Cookie` attribute][rfc-6265-5.2.6]. When truthy,
the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly` attribute is not set.
**note** be careful when setting this to `true`, as compliant clients will not allow client-side
JavaScript to see the cookie in `document.cookie`.
##### maxAge
Specifies the `number` (in seconds) to be the value for the [`Max-Age` `Set-Cookie` attribute][rfc-6265-5.2.2].
The given number will be converted to an integer by rounding down. By default, no maximum age is set.
**note** the [cookie storage model specification][rfc-6265-5.3] states that if both `expires` and
`maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this,
so if both are set, they should point to the same date and time.
##### path
Specifies the value for the [`Path` `Set-Cookie` attribute][rfc-6265-5.2.4]. By default, the path
is considered the ["default path"][rfc-6265-5.1.4].
##### sameSite
Specifies the `boolean` or `string` to be the value for the [`SameSite` `Set-Cookie` attribute][rfc-6265bis-03-4.1.2.7].
- `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
- `false` will not set the `SameSite` attribute.
- `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
- `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
- `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
More information about the different enforcement levels can be found in
[the specification][rfc-6265bis-03-4.1.2.7].
**note** This is an attribute that has not yet been fully standardized, and may change in the future.
This also means many clients may ignore this attribute until they understand it.
##### secure
Specifies the `boolean` value for the [`Secure` `Set-Cookie` attribute][rfc-6265-5.2.5]. When truthy,
the `Secure` attribute is set, otherwise it is not. By default, the `Secure` attribute is not set.
**note** be careful when setting this to `true`, as compliant clients will not send the cookie back to
the server in the future if the browser does not have an HTTPS connection.
## Example
The following example uses this module in conjunction with the Node.js core HTTP server
to prompt a user for their name and display it back on future visits.
```js
var cookie = require('cookie');
var escapeHtml = require('escape-html');
var http = require('http');
var url = require('url');
function onRequest(req, res) {
// Parse the query string
var query = url.parse(req.url, true, true).query;
if (query && query.name) {
// Set a new cookie with the name
res.setHeader('Set-Cookie', cookie.serialize('name', String(query.name), {
httpOnly: true,
maxAge: 60 * 60 * 24 * 7 // 1 week
}));
// Redirect back after setting cookie
res.statusCode = 302;
res.setHeader('Location', req.headers.referer || '/');
res.end();
return;
}
// Parse the cookies on the request
var cookies = cookie.parse(req.headers.cookie || '');
// Get the visitor name set in the cookie
var name = cookies.name;
res.setHeader('Content-Type', 'text/html; charset=UTF-8');
if (name) {
res.write('<p>Welcome back, <b>' + escapeHtml(name) + '</b>!</p>');
} else {
res.write('<p>Hello, new visitor!</p>');
}
res.write('<form method="GET">');
res.write('<input placeholder="enter your name" name="name"> <input type="submit" value="Set Name">');
res.end('</form>');
}
http.createServer(onRequest).listen(3000);
```
## Testing
```sh
$ npm test
```
## Benchmark
```
$ npm run bench
> cookie@0.4.1 bench
> node benchmark/index.js
node@16.13.1
v8@9.4.146.24-node.14
uv@1.42.0
zlib@1.2.11
brotli@1.0.9
ares@1.18.1
modules@93
nghttp2@1.45.1
napi@8
llhttp@6.0.4
openssl@1.1.1l+quic
cldr@39.0
icu@69.1
tz@2021a
unicode@13.0
ngtcp2@0.1.0-DEV
nghttp3@0.1.0-DEV
> node benchmark/parse-top.js
cookie.parse - top sites
15 tests completed.
parse accounts.google.com x 504,358 ops/sec ±6.55% (171 runs sampled)
parse apple.com x 1,369,991 ops/sec ±0.84% (189 runs sampled)
parse cloudflare.com x 360,669 ops/sec ±3.75% (182 runs sampled)
parse docs.google.com x 521,496 ops/sec ±4.90% (180 runs sampled)
parse drive.google.com x 553,514 ops/sec ±0.59% (189 runs sampled)
parse en.wikipedia.org x 286,052 ops/sec ±0.62% (188 runs sampled)
parse linkedin.com x 178,817 ops/sec ±0.61% (192 runs sampled)
parse maps.google.com x 284,585 ops/sec ±0.68% (188 runs sampled)
parse microsoft.com x 161,230 ops/sec ±0.56% (192 runs sampled)
parse play.google.com x 352,144 ops/sec ±1.01% (181 runs sampled)
parse plus.google.com x 275,204 ops/sec ±7.78% (156 runs sampled)
parse support.google.com x 339,493 ops/sec ±1.02% (191 runs sampled)
parse www.google.com x 286,110 ops/sec ±0.90% (191 runs sampled)
parse youtu.be x 548,557 ops/sec ±0.60% (184 runs sampled)
parse youtube.com x 545,293 ops/sec ±0.65% (191 runs sampled)
> node benchmark/parse.js
cookie.parse - generic
6 tests completed.
simple x 1,266,646 ops/sec ±0.65% (191 runs sampled)
decode x 838,413 ops/sec ±0.60% (191 runs sampled)
unquote x 877,820 ops/sec ±0.72% (189 runs sampled)
duplicates x 516,680 ops/sec ±0.61% (191 runs sampled)
10 cookies x 156,874 ops/sec ±0.52% (189 runs sampled)
100 cookies x 14,663 ops/sec ±0.53% (191 runs sampled)
```
## References
- [RFC 6265: HTTP State Management Mechanism][rfc-6265]
- [Same-site Cookies][rfc-6265bis-03-4.1.2.7]
[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7
[rfc-6265]: https://tools.ietf.org/html/rfc6265
[rfc-6265-5.1.4]: https://tools.ietf.org/html/rfc6265#section-5.1.4
[rfc-6265-5.2.1]: https://tools.ietf.org/html/rfc6265#section-5.2.1
[rfc-6265-5.2.2]: https://tools.ietf.org/html/rfc6265#section-5.2.2
[rfc-6265-5.2.3]: https://tools.ietf.org/html/rfc6265#section-5.2.3
[rfc-6265-5.2.4]: https://tools.ietf.org/html/rfc6265#section-5.2.4
[rfc-6265-5.2.5]: https://tools.ietf.org/html/rfc6265#section-5.2.5
[rfc-6265-5.2.6]: https://tools.ietf.org/html/rfc6265#section-5.2.6
[rfc-6265-5.3]: https://tools.ietf.org/html/rfc6265#section-5.3
## License
[MIT](LICENSE)
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/cookie/master
[coveralls-url]: https://coveralls.io/r/jshttp/cookie?branch=master
[github-actions-ci-image]: https://img.shields.io/github/workflow/status/jshttp/cookie/ci/master?label=ci
[github-actions-ci-url]: https://github.com/jshttp/cookie/actions/workflows/ci.yml
[node-version-image]: https://badgen.net/npm/node/cookie
[node-version-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/cookie
[npm-url]: https://npmjs.org/package/cookie
[npm-version-image]: https://badgen.net/npm/v/cookie

View File

@@ -0,0 +1,202 @@
/*!
* cookie
* Copyright(c) 2012-2014 Roman Shtylman
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
exports.parse = parse;
exports.serialize = serialize;
/**
* Module variables.
* @private
*/
var decode = decodeURIComponent;
var encode = encodeURIComponent;
/**
* RegExp to match field-content in RFC 7230 sec 3.2
*
* field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
* field-vchar = VCHAR / obs-text
* obs-text = %x80-FF
*/
var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
/**
* Parse a cookie header.
*
* Parse the given cookie header string into an object
* The object has the various cookies as keys(names) => values
*
* @param {string} str
* @param {object} [options]
* @return {object}
* @public
*/
function parse(str, options) {
if (typeof str !== 'string') {
throw new TypeError('argument str must be a string');
}
var obj = {}
var opt = options || {};
var pairs = str.split(';')
var dec = opt.decode || decode;
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i];
var index = pair.indexOf('=')
// skip things that don't look like key=value
if (index < 0) {
continue;
}
var key = pair.substring(0, index).trim()
// only assign once
if (undefined == obj[key]) {
var val = pair.substring(index + 1, pair.length).trim()
// quoted values
if (val[0] === '"') {
val = val.slice(1, -1)
}
obj[key] = tryDecode(val, dec);
}
}
return obj;
}
/**
* Serialize data into a cookie header.
*
* Serialize the a name value pair into a cookie string suitable for
* http headers. An optional options object specified cookie parameters.
*
* serialize('foo', 'bar', { httpOnly: true })
* => "foo=bar; httpOnly"
*
* @param {string} name
* @param {string} val
* @param {object} [options]
* @return {string}
* @public
*/
function serialize(name, val, options) {
var opt = options || {};
var enc = opt.encode || encode;
if (typeof enc !== 'function') {
throw new TypeError('option encode is invalid');
}
if (!fieldContentRegExp.test(name)) {
throw new TypeError('argument name is invalid');
}
var value = enc(val);
if (value && !fieldContentRegExp.test(value)) {
throw new TypeError('argument val is invalid');
}
var str = name + '=' + value;
if (null != opt.maxAge) {
var maxAge = opt.maxAge - 0;
if (isNaN(maxAge) || !isFinite(maxAge)) {
throw new TypeError('option maxAge is invalid')
}
str += '; Max-Age=' + Math.floor(maxAge);
}
if (opt.domain) {
if (!fieldContentRegExp.test(opt.domain)) {
throw new TypeError('option domain is invalid');
}
str += '; Domain=' + opt.domain;
}
if (opt.path) {
if (!fieldContentRegExp.test(opt.path)) {
throw new TypeError('option path is invalid');
}
str += '; Path=' + opt.path;
}
if (opt.expires) {
if (typeof opt.expires.toUTCString !== 'function') {
throw new TypeError('option expires is invalid');
}
str += '; Expires=' + opt.expires.toUTCString();
}
if (opt.httpOnly) {
str += '; HttpOnly';
}
if (opt.secure) {
str += '; Secure';
}
if (opt.sameSite) {
var sameSite = typeof opt.sameSite === 'string'
? opt.sameSite.toLowerCase() : opt.sameSite;
switch (sameSite) {
case true:
str += '; SameSite=Strict';
break;
case 'lax':
str += '; SameSite=Lax';
break;
case 'strict':
str += '; SameSite=Strict';
break;
case 'none':
str += '; SameSite=None';
break;
default:
throw new TypeError('option sameSite is invalid');
}
}
return str;
}
/**
* Try decoding a string using a decoding function.
*
* @param {string} str
* @param {function} decode
* @private
*/
function tryDecode(str, decode) {
try {
return decode(str);
} catch (e) {
return str;
}
}

View File

@@ -0,0 +1,42 @@
{
"name": "cookie",
"description": "HTTP server cookie parsing and serialization",
"version": "0.4.2",
"author": "Roman Shtylman <shtylman@gmail.com>",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>"
],
"license": "MIT",
"keywords": [
"cookie",
"cookies"
],
"repository": "jshttp/cookie",
"devDependencies": {
"beautify-benchmark": "0.2.4",
"benchmark": "2.1.4",
"eslint": "7.32.0",
"eslint-plugin-markdown": "2.2.1",
"mocha": "9.2.0",
"nyc": "15.1.0",
"top-sites": "1.1.85"
},
"files": [
"HISTORY.md",
"LICENSE",
"README.md",
"index.js"
],
"engines": {
"node": ">= 0.6"
},
"scripts": {
"bench": "node benchmark/index.js",
"lint": "eslint .",
"test": "mocha --reporter spec --bail --check-leaks --ui qunit test/",
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test",
"update-bench": "node scripts/update-benchmark.js",
"version": "node scripts/version-history.js && git add HISTORY.md"
}
}

47
node_modules/express-session/package.json generated vendored Normal file
View File

@@ -0,0 +1,47 @@
{
"name": "express-session",
"version": "1.17.3",
"description": "Simple session middleware for Express",
"author": "TJ Holowaychuk <tj@vision-media.ca> (http://tjholowaychuk.com)",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>",
"Joe Wagner <njwjs722@gmail.com>"
],
"repository": "expressjs/session",
"license": "MIT",
"dependencies": {
"cookie": "0.4.2",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "~2.0.0",
"on-headers": "~1.0.2",
"parseurl": "~1.3.3",
"safe-buffer": "5.2.1",
"uid-safe": "~2.1.5"
},
"devDependencies": {
"after": "0.8.2",
"cookie-parser": "1.4.6",
"eslint": "7.32.0",
"eslint-plugin-markdown": "2.2.1",
"express": "4.17.3",
"mocha": "10.0.0",
"nyc": "15.1.0",
"supertest": "6.2.3"
},
"files": [
"session/",
"HISTORY.md",
"index.js"
],
"engines": {
"node": ">= 0.8.0"
},
"scripts": {
"lint": "eslint . && node ./scripts/lint-readme.js",
"test": "mocha --require test/support/env --check-leaks --bail --no-exit --reporter spec test/",
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
"test-cov": "nyc npm test",
"version": "node scripts/version-history.js && git add HISTORY.md"
}
}

150
node_modules/express-session/session/cookie.js generated vendored Normal file
View File

@@ -0,0 +1,150 @@
/*!
* Connect - session - Cookie
* Copyright(c) 2010 Sencha Inc.
* Copyright(c) 2011 TJ Holowaychuk
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
*/
var cookie = require('cookie')
var deprecate = require('depd')('express-session')
/**
* Initialize a new `Cookie` with the given `options`.
*
* @param {IncomingMessage} req
* @param {Object} options
* @api private
*/
var Cookie = module.exports = function Cookie(options) {
this.path = '/';
this.maxAge = null;
this.httpOnly = true;
if (options) {
if (typeof options !== 'object') {
throw new TypeError('argument options must be a object')
}
for (var key in options) {
if (key !== 'data') {
this[key] = options[key]
}
}
}
if (this.originalMaxAge === undefined || this.originalMaxAge === null) {
this.originalMaxAge = this.maxAge
}
};
/*!
* Prototype.
*/
Cookie.prototype = {
/**
* Set expires `date`.
*
* @param {Date} date
* @api public
*/
set expires(date) {
this._expires = date;
this.originalMaxAge = this.maxAge;
},
/**
* Get expires `date`.
*
* @return {Date}
* @api public
*/
get expires() {
return this._expires;
},
/**
* Set expires via max-age in `ms`.
*
* @param {Number} ms
* @api public
*/
set maxAge(ms) {
if (ms && typeof ms !== 'number' && !(ms instanceof Date)) {
throw new TypeError('maxAge must be a number or Date')
}
if (ms instanceof Date) {
deprecate('maxAge as Date; pass number of milliseconds instead')
}
this.expires = typeof ms === 'number'
? new Date(Date.now() + ms)
: ms;
},
/**
* Get expires max-age in `ms`.
*
* @return {Number}
* @api public
*/
get maxAge() {
return this.expires instanceof Date
? this.expires.valueOf() - Date.now()
: this.expires;
},
/**
* Return cookie data object.
*
* @return {Object}
* @api private
*/
get data() {
return {
originalMaxAge: this.originalMaxAge
, expires: this._expires
, secure: this.secure
, httpOnly: this.httpOnly
, domain: this.domain
, path: this.path
, sameSite: this.sameSite
}
},
/**
* Return a serialized cookie string.
*
* @return {String}
* @api public
*/
serialize: function(name, val){
return cookie.serialize(name, val, this.data);
},
/**
* Return JSON representation of this cookie.
*
* @return {Object}
* @api private
*/
toJSON: function(){
return this.data;
}
};

187
node_modules/express-session/session/memory.js generated vendored Normal file
View File

@@ -0,0 +1,187 @@
/*!
* express-session
* Copyright(c) 2010 Sencha Inc.
* Copyright(c) 2011 TJ Holowaychuk
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
* @private
*/
var Store = require('./store')
var util = require('util')
/**
* Shim setImmediate for node.js < 0.10
* @private
*/
/* istanbul ignore next */
var defer = typeof setImmediate === 'function'
? setImmediate
: function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) }
/**
* Module exports.
*/
module.exports = MemoryStore
/**
* A session store in memory.
* @public
*/
function MemoryStore() {
Store.call(this)
this.sessions = Object.create(null)
}
/**
* Inherit from Store.
*/
util.inherits(MemoryStore, Store)
/**
* Get all active sessions.
*
* @param {function} callback
* @public
*/
MemoryStore.prototype.all = function all(callback) {
var sessionIds = Object.keys(this.sessions)
var sessions = Object.create(null)
for (var i = 0; i < sessionIds.length; i++) {
var sessionId = sessionIds[i]
var session = getSession.call(this, sessionId)
if (session) {
sessions[sessionId] = session;
}
}
callback && defer(callback, null, sessions)
}
/**
* Clear all sessions.
*
* @param {function} callback
* @public
*/
MemoryStore.prototype.clear = function clear(callback) {
this.sessions = Object.create(null)
callback && defer(callback)
}
/**
* Destroy the session associated with the given session ID.
*
* @param {string} sessionId
* @public
*/
MemoryStore.prototype.destroy = function destroy(sessionId, callback) {
delete this.sessions[sessionId]
callback && defer(callback)
}
/**
* Fetch session by the given session ID.
*
* @param {string} sessionId
* @param {function} callback
* @public
*/
MemoryStore.prototype.get = function get(sessionId, callback) {
defer(callback, null, getSession.call(this, sessionId))
}
/**
* Commit the given session associated with the given sessionId to the store.
*
* @param {string} sessionId
* @param {object} session
* @param {function} callback
* @public
*/
MemoryStore.prototype.set = function set(sessionId, session, callback) {
this.sessions[sessionId] = JSON.stringify(session)
callback && defer(callback)
}
/**
* Get number of active sessions.
*
* @param {function} callback
* @public
*/
MemoryStore.prototype.length = function length(callback) {
this.all(function (err, sessions) {
if (err) return callback(err)
callback(null, Object.keys(sessions).length)
})
}
/**
* Touch the given session object associated with the given session ID.
*
* @param {string} sessionId
* @param {object} session
* @param {function} callback
* @public
*/
MemoryStore.prototype.touch = function touch(sessionId, session, callback) {
var currentSession = getSession.call(this, sessionId)
if (currentSession) {
// update expiration
currentSession.cookie = session.cookie
this.sessions[sessionId] = JSON.stringify(currentSession)
}
callback && defer(callback)
}
/**
* Get session from the store.
* @private
*/
function getSession(sessionId) {
var sess = this.sessions[sessionId]
if (!sess) {
return
}
// parse
sess = JSON.parse(sess)
if (sess.cookie) {
var expires = typeof sess.cookie.expires === 'string'
? new Date(sess.cookie.expires)
: sess.cookie.expires
// destroy expired session
if (expires && expires <= Date.now()) {
delete this.sessions[sessionId]
return
}
}
return sess
}

143
node_modules/express-session/session/session.js generated vendored Normal file
View File

@@ -0,0 +1,143 @@
/*!
* Connect - session - Session
* Copyright(c) 2010 Sencha Inc.
* Copyright(c) 2011 TJ Holowaychuk
* MIT Licensed
*/
'use strict';
/**
* Expose Session.
*/
module.exports = Session;
/**
* Create a new `Session` with the given request and `data`.
*
* @param {IncomingRequest} req
* @param {Object} data
* @api private
*/
function Session(req, data) {
Object.defineProperty(this, 'req', { value: req });
Object.defineProperty(this, 'id', { value: req.sessionID });
if (typeof data === 'object' && data !== null) {
// merge data into this, ignoring prototype properties
for (var prop in data) {
if (!(prop in this)) {
this[prop] = data[prop]
}
}
}
}
/**
* Update reset `.cookie.maxAge` to prevent
* the cookie from expiring when the
* session is still active.
*
* @return {Session} for chaining
* @api public
*/
defineMethod(Session.prototype, 'touch', function touch() {
return this.resetMaxAge();
});
/**
* Reset `.maxAge` to `.originalMaxAge`.
*
* @return {Session} for chaining
* @api public
*/
defineMethod(Session.prototype, 'resetMaxAge', function resetMaxAge() {
this.cookie.maxAge = this.cookie.originalMaxAge;
return this;
});
/**
* Save the session data with optional callback `fn(err)`.
*
* @param {Function} fn
* @return {Session} for chaining
* @api public
*/
defineMethod(Session.prototype, 'save', function save(fn) {
this.req.sessionStore.set(this.id, this, fn || function(){});
return this;
});
/**
* Re-loads the session data _without_ altering
* the maxAge properties. Invokes the callback `fn(err)`,
* after which time if no exception has occurred the
* `req.session` property will be a new `Session` object,
* although representing the same session.
*
* @param {Function} fn
* @return {Session} for chaining
* @api public
*/
defineMethod(Session.prototype, 'reload', function reload(fn) {
var req = this.req
var store = this.req.sessionStore
store.get(this.id, function(err, sess){
if (err) return fn(err);
if (!sess) return fn(new Error('failed to load session'));
store.createSession(req, sess);
fn();
});
return this;
});
/**
* Destroy `this` session.
*
* @param {Function} fn
* @return {Session} for chaining
* @api public
*/
defineMethod(Session.prototype, 'destroy', function destroy(fn) {
delete this.req.session;
this.req.sessionStore.destroy(this.id, fn);
return this;
});
/**
* Regenerate this request's session.
*
* @param {Function} fn
* @return {Session} for chaining
* @api public
*/
defineMethod(Session.prototype, 'regenerate', function regenerate(fn) {
this.req.sessionStore.regenerate(this.req, fn);
return this;
});
/**
* Helper function for creating a method on a prototype.
*
* @param {Object} obj
* @param {String} name
* @param {Function} fn
* @private
*/
function defineMethod(obj, name, fn) {
Object.defineProperty(obj, name, {
configurable: true,
enumerable: false,
value: fn,
writable: true
});
};

102
node_modules/express-session/session/store.js generated vendored Normal file
View File

@@ -0,0 +1,102 @@
/*!
* Connect - session - Store
* Copyright(c) 2010 Sencha Inc.
* Copyright(c) 2011 TJ Holowaychuk
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
* @private
*/
var Cookie = require('./cookie')
var EventEmitter = require('events').EventEmitter
var Session = require('./session')
var util = require('util')
/**
* Module exports.
* @public
*/
module.exports = Store
/**
* Abstract base class for session stores.
* @public
*/
function Store () {
EventEmitter.call(this)
}
/**
* Inherit from EventEmitter.
*/
util.inherits(Store, EventEmitter)
/**
* Re-generate the given requests's session.
*
* @param {IncomingRequest} req
* @return {Function} fn
* @api public
*/
Store.prototype.regenerate = function(req, fn){
var self = this;
this.destroy(req.sessionID, function(err){
self.generate(req);
fn(err);
});
};
/**
* Load a `Session` instance via the given `sid`
* and invoke the callback `fn(err, sess)`.
*
* @param {String} sid
* @param {Function} fn
* @api public
*/
Store.prototype.load = function(sid, fn){
var self = this;
this.get(sid, function(err, sess){
if (err) return fn(err);
if (!sess) return fn();
var req = { sessionID: sid, sessionStore: self };
fn(null, self.createSession(req, sess))
});
};
/**
* Create session from JSON `sess` data.
*
* @param {IncomingRequest} req
* @param {Object} sess
* @return {Session}
* @api private
*/
Store.prototype.createSession = function(req, sess){
var expires = sess.cookie.expires
var originalMaxAge = sess.cookie.originalMaxAge
sess.cookie = new Cookie(sess.cookie);
if (typeof expires === 'string') {
// convert expires to a Date object
sess.cookie.expires = new Date(expires)
}
// keep originalMaxAge intact
sess.cookie.originalMaxAge = originalMaxAge
req.session = new Session(req, sess);
return req.session;
};

21
node_modules/on-headers/HISTORY.md generated vendored Normal file
View File

@@ -0,0 +1,21 @@
1.0.2 / 2019-02-21
==================
* Fix `res.writeHead` patch missing return value
1.0.1 / 2015-09-29
==================
* perf: enable strict mode
1.0.0 / 2014-08-10
==================
* Honor `res.statusCode` change in `listener`
* Move to `jshttp` organization
* Prevent `arguments`-related de-opt
0.0.0 / 2014-05-13
==================
* Initial implementation

22
node_modules/on-headers/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2014 Douglas Christopher Wilson
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.

81
node_modules/on-headers/README.md generated vendored Normal file
View File

@@ -0,0 +1,81 @@
# on-headers
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]
Execute a listener when a response is about to write headers.
## Installation
This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/). Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
```sh
$ npm install on-headers
```
## API
<!-- eslint-disable no-unused-vars -->
```js
var onHeaders = require('on-headers')
```
### onHeaders(res, listener)
This will add the listener `listener` to fire when headers are emitted for `res`.
The listener is passed the `response` object as it's context (`this`). Headers are
considered to be emitted only once, right before they are sent to the client.
When this is called multiple times on the same `res`, the `listener`s are fired
in the reverse order they were added.
## Examples
```js
var http = require('http')
var onHeaders = require('on-headers')
http
.createServer(onRequest)
.listen(3000)
function addPoweredBy () {
// set if not set by end of request
if (!this.getHeader('X-Powered-By')) {
this.setHeader('X-Powered-By', 'Node.js')
}
}
function onRequest (req, res) {
onHeaders(res, addPoweredBy)
res.setHeader('Content-Type', 'text/plain')
res.end('hello!')
}
```
## Testing
```sh
$ npm test
```
## License
[MIT](LICENSE)
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/on-headers/master
[coveralls-url]: https://coveralls.io/r/jshttp/on-headers?branch=master
[node-version-image]: https://badgen.net/npm/node/on-headers
[node-version-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/on-headers
[npm-url]: https://npmjs.org/package/on-headers
[npm-version-image]: https://badgen.net/npm/v/on-headers
[travis-image]: https://badgen.net/travis/jshttp/on-headers/master
[travis-url]: https://travis-ci.org/jshttp/on-headers

132
node_modules/on-headers/index.js generated vendored Normal file
View File

@@ -0,0 +1,132 @@
/*!
* on-headers
* Copyright(c) 2014 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module exports.
* @public
*/
module.exports = onHeaders
/**
* Create a replacement writeHead method.
*
* @param {function} prevWriteHead
* @param {function} listener
* @private
*/
function createWriteHead (prevWriteHead, listener) {
var fired = false
// return function with core name and argument list
return function writeHead (statusCode) {
// set headers from arguments
var args = setWriteHeadHeaders.apply(this, arguments)
// fire listener
if (!fired) {
fired = true
listener.call(this)
// pass-along an updated status code
if (typeof args[0] === 'number' && this.statusCode !== args[0]) {
args[0] = this.statusCode
args.length = 1
}
}
return prevWriteHead.apply(this, args)
}
}
/**
* Execute a listener when a response is about to write headers.
*
* @param {object} res
* @return {function} listener
* @public
*/
function onHeaders (res, listener) {
if (!res) {
throw new TypeError('argument res is required')
}
if (typeof listener !== 'function') {
throw new TypeError('argument listener must be a function')
}
res.writeHead = createWriteHead(res.writeHead, listener)
}
/**
* Set headers contained in array on the response object.
*
* @param {object} res
* @param {array} headers
* @private
*/
function setHeadersFromArray (res, headers) {
for (var i = 0; i < headers.length; i++) {
res.setHeader(headers[i][0], headers[i][1])
}
}
/**
* Set headers contained in object on the response object.
*
* @param {object} res
* @param {object} headers
* @private
*/
function setHeadersFromObject (res, headers) {
var keys = Object.keys(headers)
for (var i = 0; i < keys.length; i++) {
var k = keys[i]
if (k) res.setHeader(k, headers[k])
}
}
/**
* Set headers and other properties on the response object.
*
* @param {number} statusCode
* @private
*/
function setWriteHeadHeaders (statusCode) {
var length = arguments.length
var headerIndex = length > 1 && typeof arguments[1] === 'string'
? 2
: 1
var headers = length >= headerIndex + 1
? arguments[headerIndex]
: undefined
this.statusCode = statusCode
if (Array.isArray(headers)) {
// handle array case
setHeadersFromArray(this, headers)
} else if (headers) {
// handle object case
setHeadersFromObject(this, headers)
}
// copy leading arguments
var args = new Array(Math.min(length, headerIndex))
for (var i = 0; i < args.length; i++) {
args[i] = arguments[i]
}
return args
}

42
node_modules/on-headers/package.json generated vendored Normal file
View File

@@ -0,0 +1,42 @@
{
"name": "on-headers",
"description": "Execute a listener when a response is about to write headers",
"version": "1.0.2",
"author": "Douglas Christopher Wilson <doug@somethingdoug.com>",
"license": "MIT",
"keywords": [
"event",
"headers",
"http",
"onheaders"
],
"repository": "jshttp/on-headers",
"devDependencies": {
"eslint": "5.14.1",
"eslint-config-standard": "12.0.0",
"eslint-plugin-import": "2.16.0",
"eslint-plugin-markdown": "1.0.0",
"eslint-plugin-node": "8.0.1",
"eslint-plugin-promise": "4.0.1",
"eslint-plugin-standard": "4.0.0",
"istanbul": "0.4.5",
"mocha": "6.0.1",
"supertest": "3.4.2"
},
"files": [
"LICENSE",
"HISTORY.md",
"README.md",
"index.js"
],
"engines": {
"node": ">= 0.8"
},
"scripts": {
"lint": "eslint --plugin markdown --ext js,md .",
"test": "mocha --reporter spec --bail --check-leaks test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/",
"version": "node scripts/version-history.js && git add HISTORY.md"
}
}

4
node_modules/random-bytes/HISTORY.md generated vendored Normal file
View File

@@ -0,0 +1,4 @@
1.0.0 / 2016-01-17
==================
* Initial release

21
node_modules/random-bytes/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Douglas Christopher Wilson <doug@somethingdoug.com>
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.

77
node_modules/random-bytes/README.md generated vendored Normal file
View File

@@ -0,0 +1,77 @@
# random-bytes
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]
Generate strong pseudo-random bytes.
This module is a simple wrapper around the Node.js core `crypto.randomBytes` API,
with the following additions:
* A `Promise` interface for environments with promises.
* For Node.js versions that do not wait for the PRNG to be seeded, this module
will wait a bit.
## Installation
```sh
$ npm install random-bytes
```
## API
```js
var randomBytes = require('random-bytes')
```
### randomBytes(size, callback)
Generates strong pseudo-random bytes. The `size` argument is a number indicating
the number of bytes to generate.
```js
randomBytes(12, function (error, bytes) {
if (error) throw error
// do something with the bytes
})
```
### randomBytes(size)
Generates strong pseudo-random bytes and return a `Promise`. The `size` argument is
a number indicating the number of bytes to generate.
**Note**: To use promises in Node.js _prior to 0.12_, promises must be
"polyfilled" using `global.Promise = require('bluebird')`.
```js
randomBytes(18).then(function (string) {
// do something with the string
})
```
### randomBytes.sync(size)
A synchronous version of above.
```js
var bytes = randomBytes.sync(18)
```
## License
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/random-bytes.svg
[npm-url]: https://npmjs.org/package/random-bytes
[node-version-image]: https://img.shields.io/node/v/random-bytes.svg
[node-version-url]: http://nodejs.org/download/
[travis-image]: https://img.shields.io/travis/crypto-utils/random-bytes/master.svg
[travis-url]: https://travis-ci.org/crypto-utils/random-bytes
[coveralls-image]: https://img.shields.io/coveralls/crypto-utils/random-bytes/master.svg
[coveralls-url]: https://coveralls.io/r/crypto-utils/random-bytes?branch=master
[downloads-image]: https://img.shields.io/npm/dm/random-bytes.svg
[downloads-url]: https://npmjs.org/package/random-bytes

101
node_modules/random-bytes/index.js generated vendored Normal file
View File

@@ -0,0 +1,101 @@
/*!
* random-bytes
* Copyright(c) 2016 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var crypto = require('crypto')
/**
* Module variables.
* @private
*/
var generateAttempts = crypto.randomBytes === crypto.pseudoRandomBytes ? 1 : 3
/**
* Module exports.
* @public
*/
module.exports = randomBytes
module.exports.sync = randomBytesSync
/**
* Generates strong pseudo-random bytes.
*
* @param {number} size
* @param {function} [callback]
* @return {Promise}
* @public
*/
function randomBytes(size, callback) {
// validate callback is a function, if provided
if (callback !== undefined && typeof callback !== 'function') {
throw new TypeError('argument callback must be a function')
}
// require the callback without promises
if (!callback && !global.Promise) {
throw new TypeError('argument callback is required')
}
if (callback) {
// classic callback style
return generateRandomBytes(size, generateAttempts, callback)
}
return new Promise(function executor(resolve, reject) {
generateRandomBytes(size, generateAttempts, function onRandomBytes(err, str) {
if (err) return reject(err)
resolve(str)
})
})
}
/**
* Generates strong pseudo-random bytes sync.
*
* @param {number} size
* @return {Buffer}
* @public
*/
function randomBytesSync(size) {
var err = null
for (var i = 0; i < generateAttempts; i++) {
try {
return crypto.randomBytes(size)
} catch (e) {
err = e
}
}
throw err
}
/**
* Generates strong pseudo-random bytes.
*
* @param {number} size
* @param {number} attempts
* @param {function} callback
* @private
*/
function generateRandomBytes(size, attempts, callback) {
crypto.randomBytes(size, function onRandomBytes(err, buf) {
if (!err) return callback(null, buf)
if (!--attempts) return callback(err)
setTimeout(generateRandomBytes.bind(null, size, attempts, callback), 10)
})
}

36
node_modules/random-bytes/package.json generated vendored Normal file
View File

@@ -0,0 +1,36 @@
{
"name": "random-bytes",
"description": "URL and cookie safe UIDs",
"version": "1.0.0",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>"
],
"license": "MIT",
"repository": "crypto-utils/random-bytes",
"devDependencies": {
"bluebird": "3.1.1",
"istanbul": "0.4.2",
"mocha": "2.3.4",
"proxyquire": "1.2.0"
},
"files": [
"LICENSE",
"HISTORY.md",
"README.md",
"index.js"
],
"engines": {
"node": ">= 0.8"
},
"scripts": {
"test": "mocha --trace-deprecation --reporter spec --bail --check-leaks test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --trace-deprecation --reporter dot --check-leaks test/",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --trace-deprecation --reporter spec --check-leaks test/"
},
"keywords": [
"bytes",
"generator",
"random",
"safe"
]
}

61
node_modules/uid-safe/HISTORY.md generated vendored Normal file
View File

@@ -0,0 +1,61 @@
2.1.5 / 2017-08-02
==================
* perf: remove only trailing `=`
2.1.4 / 2017-03-02
==================
* Remove `base64-url` dependency
2.1.3 / 2016-10-30
==================
* deps: base64-url@1.3.3
2.1.2 / 2016-08-15
==================
* deps: base64-url@1.3.2
2.1.1 / 2016-05-04
==================
* deps: base64-url@1.2.2
2.1.0 / 2016-01-17
==================
* Use `random-bytes` for byte source
2.0.0 / 2015-05-08
==================
* Use global `Promise` when returning a promise
1.1.0 / 2015-02-01
==================
* Use `crypto.randomBytes`, if available
* deps: base64-url@1.2.1
1.0.3 / 2015-01-31
==================
* Fix error branch that would throw
* deps: base64-url@1.2.0
1.0.2 / 2015-01-08
==================
* Remove dependency on `mz`
1.0.1 / 2014-06-18
==================
* Remove direct `bluebird` dependency
1.0.0 / 2014-06-18
==================
* Initial release

22
node_modules/uid-safe/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
Copyright (c) 2015-2017 Douglas Christopher Wilson <doug@somethingdoug.com>
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.

77
node_modules/uid-safe/README.md generated vendored Normal file
View File

@@ -0,0 +1,77 @@
# uid-safe
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]
URL and cookie safe UIDs
Create cryptographically secure UIDs safe for both cookie and URL usage.
This is in contrast to modules such as [rand-token](https://www.npmjs.com/package/rand-token)
and [uid2](https://www.npmjs.com/package/uid2) whose UIDs are actually skewed
due to the use of `%` and unnecessarily truncate the UID.
Use this if you could still use UIDs with `-` and `_` in them.
## Installation
```sh
$ npm install uid-safe
```
## API
```js
var uid = require('uid-safe')
```
### uid(byteLength, callback)
Asynchronously create a UID with a specific byte length. Because `base64`
encoding is used underneath, this is not the string length. For example,
to create a UID of length 24, you want a byte length of 18.
```js
uid(18, function (err, string) {
if (err) throw err
// do something with the string
})
```
### uid(byteLength)
Asynchronously create a UID with a specific byte length and return a
`Promise`.
**Note**: To use promises in Node.js _prior to 0.12_, promises must be
"polyfilled" using `global.Promise = require('bluebird')`.
```js
uid(18).then(function (string) {
// do something with the string
})
```
### uid.sync(byteLength)
A synchronous version of above.
```js
var string = uid.sync(18)
```
## License
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/uid-safe.svg
[npm-url]: https://npmjs.org/package/uid-safe
[node-version-image]: https://img.shields.io/node/v/uid-safe.svg
[node-version-url]: https://nodejs.org/en/download/
[travis-image]: https://img.shields.io/travis/crypto-utils/uid-safe/master.svg
[travis-url]: https://travis-ci.org/crypto-utils/uid-safe
[coveralls-image]: https://img.shields.io/coveralls/crypto-utils/uid-safe/master.svg
[coveralls-url]: https://coveralls.io/r/crypto-utils/uid-safe?branch=master
[downloads-image]: https://img.shields.io/npm/dm/uid-safe.svg
[downloads-url]: https://npmjs.org/package/uid-safe

107
node_modules/uid-safe/index.js generated vendored Normal file
View File

@@ -0,0 +1,107 @@
/*!
* uid-safe
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2015-2017 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var randomBytes = require('random-bytes')
/**
* Module variables.
* @private
*/
var EQUAL_END_REGEXP = /=+$/
var PLUS_GLOBAL_REGEXP = /\+/g
var SLASH_GLOBAL_REGEXP = /\//g
/**
* Module exports.
* @public
*/
module.exports = uid
module.exports.sync = uidSync
/**
* Create a unique ID.
*
* @param {number} length
* @param {function} [callback]
* @return {Promise}
* @public
*/
function uid (length, callback) {
// validate callback is a function, if provided
if (callback !== undefined && typeof callback !== 'function') {
throw new TypeError('argument callback must be a function')
}
// require the callback without promises
if (!callback && !global.Promise) {
throw new TypeError('argument callback is required')
}
if (callback) {
// classic callback style
return generateUid(length, callback)
}
return new Promise(function executor (resolve, reject) {
generateUid(length, function onUid (err, str) {
if (err) return reject(err)
resolve(str)
})
})
}
/**
* Create a unique ID sync.
*
* @param {number} length
* @return {string}
* @public
*/
function uidSync (length) {
return toString(randomBytes.sync(length))
}
/**
* Generate a unique ID string.
*
* @param {number} length
* @param {function} callback
* @private
*/
function generateUid (length, callback) {
randomBytes(length, function (err, buf) {
if (err) return callback(err)
callback(null, toString(buf))
})
}
/**
* Change a Buffer into a string.
*
* @param {Buffer} buf
* @return {string}
* @private
*/
function toString (buf) {
return buf.toString('base64')
.replace(EQUAL_END_REGEXP, '')
.replace(PLUS_GLOBAL_REGEXP, '-')
.replace(SLASH_GLOBAL_REGEXP, '_')
}

46
node_modules/uid-safe/package.json generated vendored Normal file
View File

@@ -0,0 +1,46 @@
{
"name": "uid-safe",
"description": "URL and cookie safe UIDs",
"version": "2.1.5",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>",
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
],
"license": "MIT",
"repository": "crypto-utils/uid-safe",
"dependencies": {
"random-bytes": "~1.0.0"
},
"devDependencies": {
"bluebird": "3.5.0",
"eslint": "3.19.0",
"eslint-config-standard": "10.2.1",
"eslint-plugin-import": "2.7.0",
"eslint-plugin-node": "5.1.1",
"eslint-plugin-promise": "3.5.0",
"eslint-plugin-standard": "3.0.1",
"istanbul": "0.4.5",
"mocha": "2.5.3"
},
"files": [
"LICENSE",
"HISTORY.md",
"README.md",
"index.js"
],
"engines": {
"node": ">= 0.8"
},
"scripts": {
"lint": "eslint .",
"test": "mocha --trace-deprecation --reporter spec --bail --check-leaks test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --trace-deprecation --reporter dot --check-leaks test/",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --trace-deprecation --reporter spec --check-leaks test/"
},
"keywords": [
"random",
"generator",
"uid",
"safe"
]
}