홍지윤

create every url

every url create, gitignore txt
Showing 39 changed files with 5737 additions and 2 deletions
1 +node_modules
...\ No newline at end of file ...\ No newline at end of file
...@@ -4,13 +4,53 @@ const bodyParser = require('body-parser'); ...@@ -4,13 +4,53 @@ const bodyParser = require('body-parser');
4 const app = express(); 4 const app = express();
5 5
6 app.use(bodyParser.json()); 6 app.use(bodyParser.json());
7 -//Home
8 -app.get('/', (req,res) => res.send('Hello world!'));
9 7
8 +app.use(session({
9 + secret: 'keyboard cat',
10 + cookie: { maxAge: 60000 },
11 + resave: false,
12 + saveUninitialized: false,
13 + }));
14 +
15 +//Home
16 +app.get('/', function(req,res){
17 + res.send("Home page");
18 +})
10 //login 19 //login
20 +app.put('/login',function(req,res){
21 + res.send("Login page");
22 +})
11 //logout 23 //logout
24 +app.put('/logout',function(req,res){
25 + res.send("Logout page");
26 +})
12 //register 27 //register
28 +app.post('/register',function(req,res){
29 + res.send('register page');
30 +})
13 //Mapmain 31 //Mapmain
32 +app.get('/Mapmain',function(req,res){
33 + res.send('Mapmain page');
34 +})
35 +//Read post
36 +app.get('/Mapmain/posts/:postId',function(req,res){
37 + var postId = req.params.postId;
38 + res.send("Mapmain post page", postId);
39 +})
40 +//Create post
41 +app.post('/Mapmain/posts',function(req,res){
42 + res.send("Mapmain create page");
43 +})
44 +//Update post
45 +app.put('/Mapmain/posts/:postId',function(req,res){
46 + var postId = req.params.postId;
47 + res.send("Mapmain update page");
48 +})
49 +//Delete post
50 +app.delete('/Mapmain/posts/:postId',function(req,res){
51 + var postId = req.params.postId;
52 + res.send("Mapmain update page");
53 +})
14 //Mapmain/category/:_category 54 //Mapmain/category/:_category
15 //Mapmain/post/:_pk 55 //Mapmain/post/:_pk
16 56
......
1 +1.17.1 / 2020-04-16
2 +===================
3 +
4 + * Fix internal method wrapping error on failed reloads
5 +
6 +1.17.0 / 2019-10-10
7 +===================
8 +
9 + * deps: cookie@0.4.0
10 + - Add `SameSite=None` support
11 + * deps: safe-buffer@5.2.0
12 +
13 +1.16.2 / 2019-06-12
14 +===================
15 +
16 + * Fix restoring `cookie.originalMaxAge` when store returns `Date`
17 + * deps: parseurl@~1.3.3
18 +
19 +1.16.1 / 2019-04-11
20 +===================
21 +
22 + * Fix error passing `data` option to `Cookie` constructor
23 + * Fix uncaught error from bad session data
24 +
25 +1.16.0 / 2019-04-10
26 +===================
27 +
28 + * Catch invalid `cookie.maxAge` value earlier
29 + * Deprecate setting `cookie.maxAge` to a `Date` object
30 + * Fix issue where `resave: false` may not save altered sessions
31 + * Remove `utils-merge` dependency
32 + * Use `safe-buffer` for improved Buffer API
33 + * Use `Set-Cookie` as cookie header name for compatibility
34 + * deps: depd@~2.0.0
35 + - Replace internal `eval` usage with `Function` constructor
36 + - Use instance methods on `process` to check for listeners
37 + - perf: remove argument reassignment
38 + * deps: on-headers@~1.0.2
39 + - Fix `res.writeHead` patch missing return value
40 +
41 +1.15.6 / 2017-09-26
42 +===================
43 +
44 + * deps: debug@2.6.9
45 + * deps: parseurl@~1.3.2
46 + - perf: reduce overhead for full URLs
47 + - perf: unroll the "fast-path" `RegExp`
48 + * deps: uid-safe@~2.1.5
49 + - perf: remove only trailing `=`
50 + * deps: utils-merge@1.0.1
51 +
52 +1.15.5 / 2017-08-02
53 +===================
54 +
55 + * Fix `TypeError` when `req.url` is an empty string
56 + * deps: depd@~1.1.1
57 + - Remove unnecessary `Buffer` loading
58 +
59 +1.15.4 / 2017-07-18
60 +===================
61 +
62 + * deps: debug@2.6.8
63 +
64 +1.15.3 / 2017-05-17
65 +===================
66 +
67 + * deps: debug@2.6.7
68 + - deps: ms@2.0.0
69 +
70 +1.15.2 / 2017-03-26
71 +===================
72 +
73 + * deps: debug@2.6.3
74 + - Fix `DEBUG_MAX_ARRAY_LENGTH`
75 + * deps: uid-safe@~2.1.4
76 + - Remove `base64-url` dependency
77 +
78 +1.15.1 / 2017-02-10
79 +===================
80 +
81 + * deps: debug@2.6.1
82 + - Fix deprecation messages in WebStorm and other editors
83 + - Undeprecate `DEBUG_FD` set to `1` or `2`
84 +
85 +1.15.0 / 2017-01-22
86 +===================
87 +
88 + * Fix detecting modified session when session contains "cookie" property
89 + * Fix resaving already-saved reloaded session at end of request
90 + * deps: crc@3.4.4
91 + - perf: use `Buffer.from` when available
92 + * deps: debug@2.6.0
93 + - Allow colors in workers
94 + - Deprecated `DEBUG_FD` environment variable
95 + - Use same color for same namespace
96 + - Fix error when running under React Native
97 + - deps: ms@0.7.2
98 + * perf: remove unreachable branch in set-cookie method
99 +
100 +1.14.2 / 2016-10-30
101 +===================
102 +
103 + * deps: crc@3.4.1
104 + - Fix deprecation warning in Node.js 7.x
105 + * deps: uid-safe@~2.1.3
106 + - deps: base64-url@1.3.3
107 +
108 +1.14.1 / 2016-08-24
109 +===================
110 +
111 + * Fix not always resetting session max age before session save
112 + * Fix the cookie `sameSite` option to actually alter the `Set-Cookie`
113 + * deps: uid-safe@~2.1.2
114 + - deps: base64-url@1.3.2
115 +
116 +1.14.0 / 2016-07-01
117 +===================
118 +
119 + * Correctly inherit from `EventEmitter` class in `Store` base class
120 + * Fix issue where `Set-Cookie` `Expires` was not always updated
121 + * Methods are no longer enumerable on `req.session` object
122 + * deps: cookie@0.3.1
123 + - Add `sameSite` option
124 + - Improve error message when `encode` is not a function
125 + - Improve error message when `expires` is not a `Date`
126 + - perf: enable strict mode
127 + - perf: use for loop in parse
128 + - perf: use string concatination for serialization
129 + * deps: parseurl@~1.3.1
130 + - perf: enable strict mode
131 + * deps: uid-safe@~2.1.1
132 + - Use `random-bytes` for byte source
133 + - deps: base64-url@1.2.2
134 + * perf: enable strict mode
135 + * perf: remove argument reassignment
136 +
137 +1.13.0 / 2016-01-10
138 +===================
139 +
140 + * Fix `rolling: true` to not set cookie when no session exists
141 + - Better `saveUninitialized: false` + `rolling: true` behavior
142 + * deps: crc@3.4.0
143 +
144 +1.12.1 / 2015-10-29
145 +===================
146 +
147 + * deps: cookie@0.2.3
148 + - Fix cookie `Max-Age` to never be a floating point number
149 +
150 +1.12.0 / 2015-10-25
151 +===================
152 +
153 + * Support the value `'auto'` in the `cookie.secure` option
154 + * deps: cookie@0.2.2
155 + - Throw on invalid values provided to `serialize`
156 + * deps: depd@~1.1.0
157 + - Enable strict mode in more places
158 + - Support web browser loading
159 + * deps: on-headers@~1.0.1
160 + - perf: enable strict mode
161 +
162 +1.11.3 / 2015-05-22
163 +===================
164 +
165 + * deps: cookie@0.1.3
166 + - Slight optimizations
167 + * deps: crc@3.3.0
168 +
169 +1.11.2 / 2015-05-10
170 +===================
171 +
172 + * deps: debug@~2.2.0
173 + - deps: ms@0.7.1
174 + * deps: uid-safe@~2.0.0
175 +
176 +1.11.1 / 2015-04-08
177 +===================
178 +
179 + * Fix mutating `options.secret` value
180 +
181 +1.11.0 / 2015-04-07
182 +===================
183 +
184 + * Support an array in `secret` option for key rotation
185 + * deps: depd@~1.0.1
186 +
187 +1.10.4 / 2015-03-15
188 +===================
189 +
190 + * deps: debug@~2.1.3
191 + - Fix high intensity foreground color for bold
192 + - deps: ms@0.7.0
193 +
194 +1.10.3 / 2015-02-16
195 +===================
196 +
197 + * deps: cookie-signature@1.0.6
198 + * deps: uid-safe@1.1.0
199 + - Use `crypto.randomBytes`, if available
200 + - deps: base64-url@1.2.1
201 +
202 +1.10.2 / 2015-01-31
203 +===================
204 +
205 + * deps: uid-safe@1.0.3
206 + - Fix error branch that would throw
207 + - deps: base64-url@1.2.0
208 +
209 +1.10.1 / 2015-01-08
210 +===================
211 +
212 + * deps: uid-safe@1.0.2
213 + - Remove dependency on `mz`
214 +
215 +1.10.0 / 2015-01-05
216 +===================
217 +
218 + * Add `store.touch` interface for session stores
219 + * Fix `MemoryStore` expiration with `resave: false`
220 + * deps: debug@~2.1.1
221 +
222 +1.9.3 / 2014-12-02
223 +==================
224 +
225 + * Fix error when `req.sessionID` contains a non-string value
226 +
227 +1.9.2 / 2014-11-22
228 +==================
229 +
230 + * deps: crc@3.2.1
231 + - Minor fixes
232 +
233 +1.9.1 / 2014-10-22
234 +==================
235 +
236 + * Remove unnecessary empty write call
237 + - Fixes Node.js 0.11.14 behavior change
238 + - Helps work-around Node.js 0.10.1 zlib bug
239 +
240 +1.9.0 / 2014-09-16
241 +==================
242 +
243 + * deps: debug@~2.1.0
244 + - Implement `DEBUG_FD` env variable support
245 + * deps: depd@~1.0.0
246 +
247 +1.8.2 / 2014-09-15
248 +==================
249 +
250 + * Use `crc` instead of `buffer-crc32` for speed
251 + * deps: depd@0.4.5
252 +
253 +1.8.1 / 2014-09-08
254 +==================
255 +
256 + * Keep `req.session.save` non-enumerable
257 + * Prevent session prototype methods from being overwritten
258 +
259 +1.8.0 / 2014-09-07
260 +==================
261 +
262 + * Do not resave already-saved session at end of request
263 + * deps: cookie-signature@1.0.5
264 + * deps: debug@~2.0.0
265 +
266 +1.7.6 / 2014-08-18
267 +==================
268 +
269 + * Fix exception on `res.end(null)` calls
270 +
271 +1.7.5 / 2014-08-10
272 +==================
273 +
274 + * Fix parsing original URL
275 + * deps: on-headers@~1.0.0
276 + * deps: parseurl@~1.3.0
277 +
278 +1.7.4 / 2014-08-05
279 +==================
280 +
281 + * Fix response end delay for non-chunked responses
282 +
283 +1.7.3 / 2014-08-05
284 +==================
285 +
286 + * Fix `res.end` patch to call correct upstream `res.write`
287 +
288 +1.7.2 / 2014-07-27
289 +==================
290 +
291 + * deps: depd@0.4.4
292 + - Work-around v8 generating empty stack traces
293 +
294 +1.7.1 / 2014-07-26
295 +==================
296 +
297 + * deps: depd@0.4.3
298 + - Fix exception when global `Error.stackTraceLimit` is too low
299 +
300 +1.7.0 / 2014-07-22
301 +==================
302 +
303 + * Improve session-ending error handling
304 + - Errors are passed to `next(err)` instead of `console.error`
305 + * deps: debug@1.0.4
306 + * deps: depd@0.4.2
307 + - Add `TRACE_DEPRECATION` environment variable
308 + - Remove non-standard grey color from color output
309 + - Support `--no-deprecation` argument
310 + - Support `--trace-deprecation` argument
311 +
312 +1.6.5 / 2014-07-11
313 +==================
314 +
315 + * Do not require `req.originalUrl`
316 + * deps: debug@1.0.3
317 + - Add support for multiple wildcards in namespaces
318 +
319 +1.6.4 / 2014-07-07
320 +==================
321 +
322 + * Fix blank responses for stores with synchronous operations
323 +
324 +1.6.3 / 2014-07-04
325 +==================
326 +
327 + * Fix resave deprecation message
328 +
329 +1.6.2 / 2014-07-04
330 +==================
331 +
332 + * Fix confusing option deprecation messages
333 +
334 +1.6.1 / 2014-06-28
335 +==================
336 +
337 + * Fix saveUninitialized deprecation message
338 +
339 +1.6.0 / 2014-06-28
340 +==================
341 +
342 + * Add deprecation message to undefined `resave` option
343 + * Add deprecation message to undefined `saveUninitialized` option
344 + * Fix `res.end` patch to return correct value
345 + * Fix `res.end` patch to handle multiple `res.end` calls
346 + * Reject cookies with missing signatures
347 +
348 +1.5.2 / 2014-06-26
349 +==================
350 +
351 + * deps: cookie-signature@1.0.4
352 + - fix for timing attacks
353 +
354 +1.5.1 / 2014-06-21
355 +==================
356 +
357 + * Move hard-to-track-down `req.secret` deprecation message
358 +
359 +1.5.0 / 2014-06-19
360 +==================
361 +
362 + * Debug name is now "express-session"
363 + * Deprecate integration with `cookie-parser` middleware
364 + * Deprecate looking for secret in `req.secret`
365 + * Directly read cookies; `cookie-parser` no longer required
366 + * Directly set cookies; `res.cookie` no longer required
367 + * Generate session IDs with `uid-safe`, faster and even less collisions
368 +
369 +1.4.0 / 2014-06-17
370 +==================
371 +
372 + * Add `genid` option to generate custom session IDs
373 + * Add `saveUninitialized` option to control saving uninitialized sessions
374 + * Add `unset` option to control unsetting `req.session`
375 + * Generate session IDs with `rand-token` by default; reduce collisions
376 + * deps: buffer-crc32@0.2.3
377 +
378 +1.3.1 / 2014-06-14
379 +==================
380 +
381 + * Add description in package for npmjs.org listing
382 +
383 +1.3.0 / 2014-06-14
384 +==================
385 +
386 + * Integrate with express "trust proxy" by default
387 + * deps: debug@1.0.2
388 +
389 +1.2.1 / 2014-05-27
390 +==================
391 +
392 + * Fix `resave` such that `resave: true` works
393 +
394 +1.2.0 / 2014-05-19
395 +==================
396 +
397 + * Add `resave` option to control saving unmodified sessions
398 +
399 +1.1.0 / 2014-05-12
400 +==================
401 +
402 + * Add `name` option; replacement for `key` option
403 + * Use `setImmediate` in MemoryStore for node.js >= 0.10
404 +
405 +1.0.4 / 2014-04-27
406 +==================
407 +
408 + * deps: debug@0.8.1
409 +
410 +1.0.3 / 2014-04-19
411 +==================
412 +
413 + * Use `res.cookie()` instead of `res.setHeader()`
414 + * deps: cookie@0.1.2
415 +
416 +1.0.2 / 2014-02-23
417 +==================
418 +
419 + * Add missing dependency to `package.json`
420 +
421 +1.0.1 / 2014-02-15
422 +==================
423 +
424 + * Add missing dependencies to `package.json`
425 +
426 +1.0.0 / 2014-02-15
427 +==================
428 +
429 + * Genesis from `connect`
1 +(The MIT License)
2 +
3 +Copyright (c) 2010 Sencha Inc.
4 +Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>
5 +Copyright (c) 2014-2015 Douglas Christopher Wilson <doug@somethingdoug.com>
6 +
7 +Permission is hereby granted, free of charge, to any person obtaining
8 +a copy of this software and associated documentation files (the
9 +'Software'), to deal in the Software without restriction, including
10 +without limitation the rights to use, copy, modify, merge, publish,
11 +distribute, sublicense, and/or sell copies of the Software, and to
12 +permit persons to whom the Software is furnished to do so, subject to
13 +the following conditions:
14 +
15 +The above copyright notice and this permission notice shall be
16 +included in all copies or substantial portions of the Software.
17 +
18 +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
19 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 +# express-session
2 +
3 +[![NPM Version][npm-version-image]][npm-url]
4 +[![NPM Downloads][npm-downloads-image]][node-url]
5 +[![Build Status][travis-image]][travis-url]
6 +[![Test Coverage][coveralls-image]][coveralls-url]
7 +
8 +## Installation
9 +
10 +This is a [Node.js](https://nodejs.org/en/) module available through the
11 +[npm registry](https://www.npmjs.com/). Installation is done using the
12 +[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
13 +
14 +```sh
15 +$ npm install express-session
16 +```
17 +
18 +## API
19 +
20 +```js
21 +var session = require('express-session')
22 +```
23 +
24 +### session(options)
25 +
26 +Create a session middleware with the given `options`.
27 +
28 +**Note** Session data is _not_ saved in the cookie itself, just the session ID.
29 +Session data is stored server-side.
30 +
31 +**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser)
32 +no longer needs to be used for this module to work. This module now directly reads
33 +and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues
34 +if the `secret` is not the same between this module and `cookie-parser`.
35 +
36 +**Warning** The default server-side session storage, `MemoryStore`, is _purposely_
37 +not designed for a production environment. It will leak memory under most
38 +conditions, does not scale past a single process, and is meant for debugging and
39 +developing.
40 +
41 +For a list of stores, see [compatible session stores](#compatible-session-stores).
42 +
43 +#### Options
44 +
45 +`express-session` accepts these properties in the options object.
46 +
47 +##### cookie
48 +
49 +Settings object for the session ID cookie. The default value is
50 +`{ path: '/', httpOnly: true, secure: false, maxAge: null }`.
51 +
52 +The following are options that can be set in this object.
53 +
54 +##### cookie.domain
55 +
56 +Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain
57 +is set, and most clients will consider the cookie to apply to only the current
58 +domain.
59 +
60 +##### cookie.expires
61 +
62 +Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute.
63 +By default, no expiration is set, and most clients will consider this a
64 +"non-persistent cookie" and will delete it on a condition like exiting a web browser
65 +application.
66 +
67 +**Note** If both `expires` and `maxAge` are set in the options, then the last one
68 +defined in the object is what is used.
69 +
70 +**Note** The `expires` option should not be set directly; instead only use the `maxAge`
71 +option.
72 +
73 +##### cookie.httpOnly
74 +
75 +Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy,
76 +the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly`
77 +attribute is set.
78 +
79 +**Note** be careful when setting this to `true`, as compliant clients will not allow
80 +client-side JavaScript to see the cookie in `document.cookie`.
81 +
82 +##### cookie.maxAge
83 +
84 +Specifies the `number` (in milliseconds) to use when calculating the `Expires`
85 +`Set-Cookie` attribute. This is done by taking the current server time and adding
86 +`maxAge` milliseconds to the value to calculate an `Expires` datetime. By default,
87 +no maximum age is set.
88 +
89 +**Note** If both `expires` and `maxAge` are set in the options, then the last one
90 +defined in the object is what is used.
91 +
92 +##### cookie.path
93 +
94 +Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which
95 +is the root path of the domain.
96 +
97 +##### cookie.sameSite
98 +
99 +Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute.
100 +
101 + - `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
102 + - `false` will not set the `SameSite` attribute.
103 + - `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
104 + - `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
105 + - `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
106 +
107 +More information about the different enforcement levels can be found in
108 +[the specification][rfc-6265bis-03-4.1.2.7].
109 +
110 +**Note** This is an attribute that has not yet been fully standardized, and may change in
111 +the future. This also means many clients may ignore this attribute until they understand it.
112 +
113 +##### cookie.secure
114 +
115 +Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy,
116 +the `Secure` attribute is set, otherwise it is not. By default, the `Secure`
117 +attribute is not set.
118 +
119 +**Note** be careful when setting this to `true`, as compliant clients will not send
120 +the cookie back to the server in the future if the browser does not have an HTTPS
121 +connection.
122 +
123 +Please note that `secure: true` is a **recommended** option. However, it requires
124 +an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure`
125 +is set, and you access your site over HTTP, the cookie will not be set. If you
126 +have your node.js behind a proxy and are using `secure: true`, you need to set
127 +"trust proxy" in express:
128 +
129 +```js
130 +var app = express()
131 +app.set('trust proxy', 1) // trust first proxy
132 +app.use(session({
133 + secret: 'keyboard cat',
134 + resave: false,
135 + saveUninitialized: true,
136 + cookie: { secure: true }
137 +}))
138 +```
139 +
140 +For using secure cookies in production, but allowing for testing in development,
141 +the following is an example of enabling this setup based on `NODE_ENV` in express:
142 +
143 +```js
144 +var app = express()
145 +var sess = {
146 + secret: 'keyboard cat',
147 + cookie: {}
148 +}
149 +
150 +if (app.get('env') === 'production') {
151 + app.set('trust proxy', 1) // trust first proxy
152 + sess.cookie.secure = true // serve secure cookies
153 +}
154 +
155 +app.use(session(sess))
156 +```
157 +
158 +The `cookie.secure` option can also be set to the special value `'auto'` to have
159 +this setting automatically match the determined security of the connection. Be
160 +careful when using this setting if the site is available both as HTTP and HTTPS,
161 +as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This
162 +is useful when the Express `"trust proxy"` setting is properly setup to simplify
163 +development vs production configuration.
164 +
165 +##### genid
166 +
167 +Function to call to generate a new session ID. Provide a function that returns
168 +a string that will be used as a session ID. The function is given `req` as the
169 +first argument if you want to use some value attached to `req` when generating
170 +the ID.
171 +
172 +The default value is a function which uses the `uid-safe` library to generate IDs.
173 +
174 +**NOTE** be careful to generate unique IDs so your sessions do not conflict.
175 +
176 +```js
177 +app.use(session({
178 + genid: function(req) {
179 + return genuuid() // use UUIDs for session IDs
180 + },
181 + secret: 'keyboard cat'
182 +}))
183 +```
184 +
185 +##### name
186 +
187 +The name of the session ID cookie to set in the response (and read from in the
188 +request).
189 +
190 +The default value is `'connect.sid'`.
191 +
192 +**Note** if you have multiple apps running on the same hostname (this is just
193 +the name, i.e. `localhost` or `127.0.0.1`; different schemes and ports do not
194 +name a different hostname), then you need to separate the session cookies from
195 +each other. The simplest method is to simply set different `name`s per app.
196 +
197 +##### proxy
198 +
199 +Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto"
200 +header).
201 +
202 +The default value is `undefined`.
203 +
204 + - `true` The "X-Forwarded-Proto" header will be used.
205 + - `false` All headers are ignored and the connection is considered secure only
206 + if there is a direct TLS/SSL connection.
207 + - `undefined` Uses the "trust proxy" setting from express
208 +
209 +##### resave
210 +
211 +Forces the session to be saved back to the session store, even if the session
212 +was never modified during the request. Depending on your store this may be
213 +necessary, but it can also create race conditions where a client makes two
214 +parallel requests to your server and changes made to the session in one
215 +request may get overwritten when the other request ends, even if it made no
216 +changes (this behavior also depends on what store you're using).
217 +
218 +The default value is `true`, but using the default has been deprecated,
219 +as the default will change in the future. Please research into this setting
220 +and choose what is appropriate to your use-case. Typically, you'll want
221 +`false`.
222 +
223 +How do I know if this is necessary for my store? The best way to know is to
224 +check with your store if it implements the `touch` method. If it does, then
225 +you can safely set `resave: false`. If it does not implement the `touch`
226 +method and your store sets an expiration date on stored sessions, then you
227 +likely need `resave: true`.
228 +
229 +##### rolling
230 +
231 +Force the session identifier cookie to be set on every response. The expiration
232 +is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration
233 +countdown.
234 +
235 +The default value is `false`.
236 +
237 +With this enabled, the session identifier cookie will expire in
238 +[`maxAge`](#cookiemaxage) since the last response was sent instead of in
239 +[`maxAge`](#cookiemaxage) since the session was last modified by the server.
240 +
241 +This is typically used in conjuction with short, non-session-length
242 +[`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data
243 +with reduced potentional of it occurring during on going server interactions.
244 +
245 +**Note** When this option is set to `true` but the `saveUninitialized` option is
246 +set to `false`, the cookie will not be set on a response with an uninitialized
247 +session. This option only modifies the behavior when an existing session was
248 +loaded for the request.
249 +
250 +##### saveUninitialized
251 +
252 +Forces a session that is "uninitialized" to be saved to the store. A session is
253 +uninitialized when it is new but not modified. Choosing `false` is useful for
254 +implementing login sessions, reducing server storage usage, or complying with
255 +laws that require permission before setting a cookie. Choosing `false` will also
256 +help with race conditions where a client makes multiple parallel requests
257 +without a session.
258 +
259 +The default value is `true`, but using the default has been deprecated, as the
260 +default will change in the future. Please research into this setting and
261 +choose what is appropriate to your use-case.
262 +
263 +**Note** if you are using Session in conjunction with PassportJS, Passport
264 +will add an empty Passport object to the session for use after a user is
265 +authenticated, which will be treated as a modification to the session, causing
266 +it to be saved. *This has been fixed in PassportJS 0.3.0*
267 +
268 +##### secret
269 +
270 +**Required option**
271 +
272 +This is the secret used to sign the session ID cookie. This can be either a string
273 +for a single secret, or an array of multiple secrets. If an array of secrets is
274 +provided, only the first element will be used to sign the session ID cookie, while
275 +all the elements will be considered when verifying the signature in requests.
276 +
277 +##### store
278 +
279 +The session store instance, defaults to a new `MemoryStore` instance.
280 +
281 +##### unset
282 +
283 +Control the result of unsetting `req.session` (through `delete`, setting to `null`,
284 +etc.).
285 +
286 +The default value is `'keep'`.
287 +
288 + - `'destroy'` The session will be destroyed (deleted) when the response ends.
289 + - `'keep'` The session in the store will be kept, but modifications made during
290 + the request are ignored and not saved.
291 +
292 +### req.session
293 +
294 +To store or access session data, simply use the request property `req.session`,
295 +which is (generally) serialized as JSON by the store, so nested objects
296 +are typically fine. For example below is a user-specific view counter:
297 +
298 +```js
299 +// Use the session middleware
300 +app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))
301 +
302 +// Access the session as req.session
303 +app.get('/', function(req, res, next) {
304 + if (req.session.views) {
305 + req.session.views++
306 + res.setHeader('Content-Type', 'text/html')
307 + res.write('<p>views: ' + req.session.views + '</p>')
308 + res.write('<p>expires in: ' + (req.session.cookie.maxAge / 1000) + 's</p>')
309 + res.end()
310 + } else {
311 + req.session.views = 1
312 + res.end('welcome to the session demo. refresh!')
313 + }
314 +})
315 +```
316 +
317 +#### Session.regenerate(callback)
318 +
319 +To regenerate the session simply invoke the method. Once complete,
320 +a new SID and `Session` instance will be initialized at `req.session`
321 +and the `callback` will be invoked.
322 +
323 +```js
324 +req.session.regenerate(function(err) {
325 + // will have a new session here
326 +})
327 +```
328 +
329 +#### Session.destroy(callback)
330 +
331 +Destroys the session and will unset the `req.session` property.
332 +Once complete, the `callback` will be invoked.
333 +
334 +```js
335 +req.session.destroy(function(err) {
336 + // cannot access session here
337 +})
338 +```
339 +
340 +#### Session.reload(callback)
341 +
342 +Reloads the session data from the store and re-populates the
343 +`req.session` object. Once complete, the `callback` will be invoked.
344 +
345 +```js
346 +req.session.reload(function(err) {
347 + // session updated
348 +})
349 +```
350 +
351 +#### Session.save(callback)
352 +
353 +Save the session back to the store, replacing the contents on the store with the
354 +contents in memory (though a store may do something else--consult the store's
355 +documentation for exact behavior).
356 +
357 +This method is automatically called at the end of the HTTP response if the
358 +session data has been altered (though this behavior can be altered with various
359 +options in the middleware constructor). Because of this, typically this method
360 +does not need to be called.
361 +
362 +There are some cases where it is useful to call this method, for example,
363 +redirects, long-lived requests or in WebSockets.
364 +
365 +```js
366 +req.session.save(function(err) {
367 + // session saved
368 +})
369 +```
370 +
371 +#### Session.touch()
372 +
373 +Updates the `.maxAge` property. Typically this is
374 +not necessary to call, as the session middleware does this for you.
375 +
376 +### req.session.id
377 +
378 +Each session has a unique ID associated with it. This property is an
379 +alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified.
380 +It has been added to make the session ID accessible from the `session`
381 +object.
382 +
383 +### req.session.cookie
384 +
385 +Each session has a unique cookie object accompany it. This allows
386 +you to alter the session cookie per visitor. For example we can
387 +set `req.session.cookie.expires` to `false` to enable the cookie
388 +to remain for only the duration of the user-agent.
389 +
390 +#### Cookie.maxAge
391 +
392 +Alternatively `req.session.cookie.maxAge` will return the time
393 +remaining in milliseconds, which we may also re-assign a new value
394 +to adjust the `.expires` property appropriately. The following
395 +are essentially equivalent
396 +
397 +```js
398 +var hour = 3600000
399 +req.session.cookie.expires = new Date(Date.now() + hour)
400 +req.session.cookie.maxAge = hour
401 +```
402 +
403 +For example when `maxAge` is set to `60000` (one minute), and 30 seconds
404 +has elapsed it will return `30000` until the current request has completed,
405 +at which time `req.session.touch()` is called to reset
406 +`req.session.cookie.maxAge` to its original value.
407 +
408 +```js
409 +req.session.cookie.maxAge // => 30000
410 +```
411 +
412 +#### Cookie.originalMaxAge
413 +
414 +The `req.session.cookie.originalMaxAge` property returns the original
415 +`maxAge` (time-to-live), in milliseconds, of the session cookie.
416 +
417 +### req.sessionID
418 +
419 +To get the ID of the loaded session, access the request property
420 +`req.sessionID`. This is simply a read-only value set when a session
421 +is loaded/created.
422 +
423 +## Session Store Implementation
424 +
425 +Every session store _must_ be an `EventEmitter` and implement specific
426 +methods. The following methods are the list of **required**, **recommended**,
427 +and **optional**.
428 +
429 + * Required methods are ones that this module will always call on the store.
430 + * Recommended methods are ones that this module will call on the store if
431 + available.
432 + * Optional methods are ones this module does not call at all, but helps
433 + present uniform stores to users.
434 +
435 +For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
436 +
437 +### store.all(callback)
438 +
439 +**Optional**
440 +
441 +This optional method is used to get all sessions in the store as an array. The
442 +`callback` should be called as `callback(error, sessions)`.
443 +
444 +### store.destroy(sid, callback)
445 +
446 +**Required**
447 +
448 +This required method is used to destroy/delete a session from the store given
449 +a session ID (`sid`). The `callback` should be called as `callback(error)` once
450 +the session is destroyed.
451 +
452 +### store.clear(callback)
453 +
454 +**Optional**
455 +
456 +This optional method is used to delete all sessions from the store. The
457 +`callback` should be called as `callback(error)` once the store is cleared.
458 +
459 +### store.length(callback)
460 +
461 +**Optional**
462 +
463 +This optional method is used to get the count of all sessions in the store.
464 +The `callback` should be called as `callback(error, len)`.
465 +
466 +### store.get(sid, callback)
467 +
468 +**Required**
469 +
470 +This required method is used to get a session from the store given a session
471 +ID (`sid`). The `callback` should be called as `callback(error, session)`.
472 +
473 +The `session` argument should be a session if found, otherwise `null` or
474 +`undefined` if the session was not found (and there was no error). A special
475 +case is made when `error.code === 'ENOENT'` to act like `callback(null, null)`.
476 +
477 +### store.set(sid, session, callback)
478 +
479 +**Required**
480 +
481 +This required method is used to upsert a session into the store given a
482 +session ID (`sid`) and session (`session`) object. The callback should be
483 +called as `callback(error)` once the session has been set in the store.
484 +
485 +### store.touch(sid, session, callback)
486 +
487 +**Recommended**
488 +
489 +This recommended method is used to "touch" a given session given a
490 +session ID (`sid`) and session (`session`) object. The `callback` should be
491 +called as `callback(error)` once the session has been touched.
492 +
493 +This is primarily used when the store will automatically delete idle sessions
494 +and this method is used to signal to the store the given session is active,
495 +potentially resetting the idle timer.
496 +
497 +## Compatible Session Stores
498 +
499 +The following modules implement a session store that is compatible with this
500 +module. Please make a PR to add additional modules :)
501 +
502 +[![★][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] A session store using [Aerospike](http://www.aerospike.com/).
503 +
504 +[aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store
505 +[aerospike-session-store-image]: https://badgen.net/github/stars/aerospike/aerospike-session-store-expressjs?label=%E2%98%85
506 +
507 +[![★][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store.
508 +
509 +[cassandra-store-url]: https://www.npmjs.com/package/cassandra-store
510 +[cassandra-store-image]: https://badgen.net/github/stars/webcc/cassandra-store?label=%E2%98%85
511 +
512 +[![★][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded
513 +stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2
514 +and other multi-core embedded devices).
515 +
516 +[cluster-store-url]: https://www.npmjs.com/package/cluster-store
517 +[cluster-store-image]: https://badgen.net/github/stars/coolaj86/cluster-store?label=%E2%98%85
518 +
519 +[![★][connect-arango-image] connect-arango][connect-arango-url] An ArangoDB-based session store.
520 +
521 +[connect-arango-url]: https://www.npmjs.com/package/connect-arango
522 +[connect-arango-image]: https://badgen.net/github/stars/AlexanderArvidsson/connect-arango?label=%E2%98%85
523 +
524 +[![★][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store.
525 +
526 +[connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables
527 +[connect-azuretables-image]: https://badgen.net/github/stars/mike-goodwin/connect-azuretables?label=%E2%98%85
528 +
529 +[![★][connect-cloudant-store-image] connect-cloudant-store][connect-cloudant-store-url] An [IBM Cloudant](https://cloudant.com/)-based session store.
530 +
531 +[connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store
532 +[connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85
533 +
534 +[![★][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store.
535 +
536 +[connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase
537 +[connect-couchbase-image]: https://badgen.net/github/stars/christophermina/connect-couchbase?label=%E2%98%85
538 +
539 +[![★][connect-datacache-image] connect-datacache][connect-datacache-url] An [IBM Bluemix Data Cache](http://www.ibm.com/cloud-computing/bluemix/)-based session store.
540 +
541 +[connect-datacache-url]: https://www.npmjs.com/package/connect-datacache
542 +[connect-datacache-image]: https://badgen.net/github/stars/adriantanasa/connect-datacache?label=%E2%98%85
543 +
544 +[![★][@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.
545 +
546 +[@google-cloud/connect-datastore-url]: https://www.npmjs.com/package/@google-cloud/connect-datastore
547 +[@google-cloud/connect-datastore-image]: https://badgen.net/github/stars/GoogleCloudPlatform/cloud-datastore-session-node?label=%E2%98%85
548 +
549 +[![★][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.
550 +
551 +[connect-db2-url]: https://www.npmjs.com/package/connect-db2
552 +[connect-db2-image]: https://badgen.net/github/stars/wallali/connect-db2?label=%E2%98%85
553 +
554 +[![★][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store.
555 +
556 +[connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb
557 +[connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85
558 +
559 +[![★][@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.
560 +
561 +[@google-cloud/connect-firestore-url]: https://www.npmjs.com/package/@google-cloud/connect-firestore
562 +[@google-cloud/connect-firestore-image]: https://badgen.net/github/stars/googleapis/nodejs-firestore-session?label=%E2%98%85
563 +
564 +[![★][connect-hazelcast-image] connect-hazelcast][connect-hazelcast-url] Hazelcast session store for Connect and Express.
565 +
566 +[connect-hazelcast-url]: https://www.npmjs.com/package/connect-hazelcast
567 +[connect-hazelcast-image]: https://badgen.net/github/stars/huseyinbabal/connect-hazelcast?label=%E2%98%85
568 +
569 +[![★][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store.
570 +
571 +[connect-loki-url]: https://www.npmjs.com/package/connect-loki
572 +[connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85
573 +
574 +[![★][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store.
575 +
576 +[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached
577 +[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85
578 +
579 +[![★][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using
580 +[memjs](https://www.npmjs.com/package/memjs) as the memcached client.
581 +
582 +[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs
583 +[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85
584 +
585 +[![★][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store.
586 +
587 +[connect-ml-url]: https://www.npmjs.com/package/connect-ml
588 +[connect-ml-image]: https://badgen.net/github/stars/bluetorch/connect-ml?label=%E2%98%85
589 +
590 +[![★][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store.
591 +
592 +[connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb
593 +[connect-monetdb-image]: https://badgen.net/github/stars/MonetDB/npm-connect-monetdb?label=%E2%98%85
594 +
595 +[![★][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store.
596 +
597 +[connect-mongo-url]: https://www.npmjs.com/package/connect-mongo
598 +[connect-mongo-image]: https://badgen.net/github/stars/kcbanner/connect-mongo?label=%E2%98%85
599 +
600 +[![★][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB.
601 +
602 +[connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session
603 +[connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85
604 +
605 +[![★][connect-mssql-image] connect-mssql][connect-mssql-url] A SQL Server-based session store.
606 +
607 +[connect-mssql-url]: https://www.npmjs.com/package/connect-mssql
608 +[connect-mssql-image]: https://badgen.net/github/stars/patriksimek/connect-mssql?label=%E2%98%85
609 +
610 +[![★][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store.
611 +
612 +[connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple
613 +[connect-pg-simple-image]: https://badgen.net/github/stars/voxpelli/node-connect-pg-simple?label=%E2%98%85
614 +
615 +[![★][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store.
616 +
617 +[connect-redis-url]: https://www.npmjs.com/package/connect-redis
618 +[connect-redis-image]: https://badgen.net/github/stars/tj/connect-redis?label=%E2%98%85
619 +
620 +[![★][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/)
621 +
622 +[connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase
623 +[connect-session-firebase-image]: https://badgen.net/github/stars/benweier/connect-session-firebase?label=%E2%98%85
624 +
625 +[![★][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using
626 +[Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle.
627 +
628 +[connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex
629 +[connect-session-knex-image]: https://badgen.net/github/stars/llambda/connect-session-knex?label=%E2%98%85
630 +
631 +[![★][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using
632 +[Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL.
633 +
634 +[connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize
635 +[connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85
636 +
637 +[![★][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.
638 +
639 +[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3
640 +[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85
641 +
642 +[![★][connect-typeorm-image] connect-typeorm][connect-typeorm-url] A [TypeORM](https://github.com/typeorm/typeorm)-based session store.
643 +
644 +[connect-typeorm-url]: https://www.npmjs.com/package/connect-typeorm
645 +[connect-typeorm-image]: https://badgen.net/github/stars/makepost/connect-typeorm?label=%E2%98%85
646 +
647 +[![★][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store.
648 +
649 +[couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression
650 +[couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85
651 +
652 +[![★][documentdb-session-image] documentdb-session][documentdb-session-url] A session store for Microsoft Azure's [DocumentDB](https://azure.microsoft.com/en-us/services/documentdb/) NoSQL database service.
653 +
654 +[documentdb-session-url]: https://www.npmjs.com/package/documentdb-session
655 +[documentdb-session-image]: https://badgen.net/github/stars/dwhieb/documentdb-session?label=%E2%98%85
656 +
657 +[![★][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store.
658 +
659 +[dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store
660 +[dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85
661 +
662 +[![★][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store.
663 +
664 +[express-etcd-url]: https://www.npmjs.com/package/express-etcd
665 +[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85
666 +
667 +[![★][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native
668 +[MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module.
669 +
670 +[express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session
671 +[express-mysql-session-image]: https://badgen.net/github/stars/chill117/express-mysql-session?label=%E2%98%85
672 +
673 +[![★][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store.
674 +
675 +[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session
676 +[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85
677 +
678 +[![★][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native
679 +[oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module.
680 +
681 +[express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session
682 +[express-oracle-session-image]: https://badgen.net/github/stars/slumber86/express-oracle-session?label=%E2%98%85
683 +
684 +[![★][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url]
685 +A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports
686 +a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines).
687 +
688 +[express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager
689 +[express-session-cache-manager-image]: https://badgen.net/github/stars/theogravity/express-session-cache-manager?label=%E2%98%85
690 +
691 +[![★][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store.
692 +
693 +[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3
694 +[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85
695 +
696 +[![★][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store.
697 +
698 +[express-session-level-url]: https://www.npmjs.com/package/express-session-level
699 +[express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85
700 +
701 +[![★][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.
702 +
703 +[express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb
704 +[express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85
705 +
706 +[![★][express-sessions-image] express-sessions][express-sessions-url] A session store supporting both MongoDB and Redis.
707 +
708 +[express-sessions-url]: https://www.npmjs.com/package/express-sessions
709 +[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85
710 +
711 +[![★][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store.
712 +
713 +[firestore-store-url]: https://www.npmjs.com/package/firestore-store
714 +[firestore-store-image]: https://badgen.net/github/stars/hendrysadrak/firestore-store?label=%E2%98%85
715 +
716 +[![★][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune)
717 +based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB).
718 +
719 +[fortune-session-url]: https://www.npmjs.com/package/fortune-session
720 +[fortune-session-image]: https://badgen.net/github/stars/aliceklipper/fortune-session?label=%E2%98%85
721 +
722 +[![★][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).
723 +
724 +[hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store
725 +[hazelcast-store-image]: https://badgen.net/github/stars/jackspaniel/hazelcast-store?label=%E2%98%85
726 +
727 +[![★][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store.
728 +
729 +[level-session-store-url]: https://www.npmjs.com/package/level-session-store
730 +[level-session-store-image]: https://badgen.net/github/stars/toddself/level-session-store?label=%E2%98%85
731 +
732 +[![★][lowdb-session-store-image] lowdb-session-store][lowdb-session-store-url] A [lowdb](https://www.npmjs.com/package/lowdb)-based session store.
733 +
734 +[lowdb-session-store-url]: https://www.npmjs.com/package/lowdb-session-store
735 +[lowdb-session-store-image]: https://badgen.net/github/stars/fhellwig/lowdb-session-store?label=%E2%98%85
736 +
737 +[![★][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store.
738 +
739 +[medea-session-store-url]: https://www.npmjs.com/package/medea-session-store
740 +[medea-session-store-image]: https://badgen.net/github/stars/BenjaminVadant/medea-session-store?label=%E2%98%85
741 +
742 +[![★][memorystore-image] memorystore][memorystore-url] A memory session store made for production.
743 +
744 +[memorystore-url]: https://www.npmjs.com/package/memorystore
745 +[memorystore-image]: https://badgen.net/github/stars/roccomuso/memorystore?label=%E2%98%85
746 +
747 +[![★][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store.
748 +
749 +[mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store
750 +[mssql-session-store-image]: https://badgen.net/github/stars/jwathen/mssql-session-store?label=%E2%98%85
751 +
752 +[![★][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store.
753 +
754 +[nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store
755 +[nedb-session-store-image]: https://badgen.net/github/stars/JamesMGreene/nedb-session-store?label=%E2%98%85
756 +
757 +[![★][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API
758 +
759 +[restsession-url]: https://www.npmjs.com/package/restsession
760 +[restsession-image]: https://badgen.net/github/stars/jankal/restsession?label=%E2%98%85
761 +
762 +[![★][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/).
763 +
764 +[sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect
765 +[sequelstore-connect-image]: https://badgen.net/github/stars/MattMcFarland/sequelstore-connect?label=%E2%98%85
766 +
767 +[![★][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store.
768 +
769 +[session-file-store-url]: https://www.npmjs.com/package/session-file-store
770 +[session-file-store-image]: https://badgen.net/github/stars/valery-barysok/session-file-store?label=%E2%98%85
771 +
772 +[![★][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.
773 +
774 +[session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store
775 +[session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85
776 +
777 +[![★][session-rethinkdb-image] session-rethinkdb][session-rethinkdb-url] A [RethinkDB](http://rethinkdb.com/)-based session store.
778 +
779 +[session-rethinkdb-url]: https://www.npmjs.com/package/session-rethinkdb
780 +[session-rethinkdb-image]: https://badgen.net/github/stars/llambda/session-rethinkdb?label=%E2%98%85
781 +
782 +[![★][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases.
783 +
784 +[sessionstore-url]: https://www.npmjs.com/package/sessionstore
785 +[sessionstore-image]: https://badgen.net/github/stars/adrai/sessionstore?label=%E2%98%85
786 +
787 +[![★][tch-nedb-session-image] tch-nedb-session][tch-nedb-session-url] A file system session store based on NeDB.
788 +
789 +[tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session
790 +[tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85
791 +
792 +## Example
793 +
794 +A simple example using `express-session` to store page views for a user.
795 +
796 +```js
797 +var express = require('express')
798 +var parseurl = require('parseurl')
799 +var session = require('express-session')
800 +
801 +var app = express()
802 +
803 +app.use(session({
804 + secret: 'keyboard cat',
805 + resave: false,
806 + saveUninitialized: true
807 +}))
808 +
809 +app.use(function (req, res, next) {
810 + if (!req.session.views) {
811 + req.session.views = {}
812 + }
813 +
814 + // get the url pathname
815 + var pathname = parseurl(req).pathname
816 +
817 + // count the views
818 + req.session.views[pathname] = (req.session.views[pathname] || 0) + 1
819 +
820 + next()
821 +})
822 +
823 +app.get('/foo', function (req, res, next) {
824 + res.send('you viewed this page ' + req.session.views['/foo'] + ' times')
825 +})
826 +
827 +app.get('/bar', function (req, res, next) {
828 + res.send('you viewed this page ' + req.session.views['/bar'] + ' times')
829 +})
830 +```
831 +
832 +## Debugging
833 +
834 +This module uses the [debug](https://www.npmjs.com/package/debug) module
835 +internally to log information about session operations.
836 +
837 +To see all the internal logs, set the `DEBUG` environment variable to
838 +`express-session` when launching your app (`npm start`, in this example):
839 +
840 +```sh
841 +$ DEBUG=express-session npm start
842 +```
843 +
844 +On Windows, use the corresponding command;
845 +
846 +```sh
847 +> set DEBUG=express-session & npm start
848 +```
849 +
850 +## License
851 +
852 +[MIT](LICENSE)
853 +
854 +[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7
855 +[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master
856 +[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master
857 +[node-url]: https://nodejs.org/en/download
858 +[npm-downloads-image]: https://badgen.net/npm/dm/express-session
859 +[npm-url]: https://npmjs.org/package/express-session
860 +[npm-version-image]: https://badgen.net/npm/v/express-session
861 +[travis-image]: https://badgen.net/travis/expressjs/session/master
862 +[travis-url]: https://travis-ci.org/expressjs/session
1 +/*!
2 + * express-session
3 + * Copyright(c) 2010 Sencha Inc.
4 + * Copyright(c) 2011 TJ Holowaychuk
5 + * Copyright(c) 2014-2015 Douglas Christopher Wilson
6 + * MIT Licensed
7 + */
8 +
9 +'use strict';
10 +
11 +/**
12 + * Module dependencies.
13 + * @private
14 + */
15 +
16 +var Buffer = require('safe-buffer').Buffer
17 +var cookie = require('cookie');
18 +var crypto = require('crypto')
19 +var debug = require('debug')('express-session');
20 +var deprecate = require('depd')('express-session');
21 +var onHeaders = require('on-headers')
22 +var parseUrl = require('parseurl');
23 +var signature = require('cookie-signature')
24 +var uid = require('uid-safe').sync
25 +
26 +var Cookie = require('./session/cookie')
27 +var MemoryStore = require('./session/memory')
28 +var Session = require('./session/session')
29 +var Store = require('./session/store')
30 +
31 +// environment
32 +
33 +var env = process.env.NODE_ENV;
34 +
35 +/**
36 + * Expose the middleware.
37 + */
38 +
39 +exports = module.exports = session;
40 +
41 +/**
42 + * Expose constructors.
43 + */
44 +
45 +exports.Store = Store;
46 +exports.Cookie = Cookie;
47 +exports.Session = Session;
48 +exports.MemoryStore = MemoryStore;
49 +
50 +/**
51 + * Warning message for `MemoryStore` usage in production.
52 + * @private
53 + */
54 +
55 +var warning = 'Warning: connect.session() MemoryStore is not\n'
56 + + 'designed for a production environment, as it will leak\n'
57 + + 'memory, and will not scale past a single process.';
58 +
59 +/**
60 + * Node.js 0.8+ async implementation.
61 + * @private
62 + */
63 +
64 +/* istanbul ignore next */
65 +var defer = typeof setImmediate === 'function'
66 + ? setImmediate
67 + : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) }
68 +
69 +/**
70 + * Setup session store with the given `options`.
71 + *
72 + * @param {Object} [options]
73 + * @param {Object} [options.cookie] Options for cookie
74 + * @param {Function} [options.genid]
75 + * @param {String} [options.name=connect.sid] Session ID cookie name
76 + * @param {Boolean} [options.proxy]
77 + * @param {Boolean} [options.resave] Resave unmodified sessions back to the store
78 + * @param {Boolean} [options.rolling] Enable/disable rolling session expiration
79 + * @param {Boolean} [options.saveUninitialized] Save uninitialized sessions to the store
80 + * @param {String|Array} [options.secret] Secret for signing session ID
81 + * @param {Object} [options.store=MemoryStore] Session store
82 + * @param {String} [options.unset]
83 + * @return {Function} middleware
84 + * @public
85 + */
86 +
87 +function session(options) {
88 + var opts = options || {}
89 +
90 + // get the cookie options
91 + var cookieOptions = opts.cookie || {}
92 +
93 + // get the session id generate function
94 + var generateId = opts.genid || generateSessionId
95 +
96 + // get the session cookie name
97 + var name = opts.name || opts.key || 'connect.sid'
98 +
99 + // get the session store
100 + var store = opts.store || new MemoryStore()
101 +
102 + // get the trust proxy setting
103 + var trustProxy = opts.proxy
104 +
105 + // get the resave session option
106 + var resaveSession = opts.resave;
107 +
108 + // get the rolling session option
109 + var rollingSessions = Boolean(opts.rolling)
110 +
111 + // get the save uninitialized session option
112 + var saveUninitializedSession = opts.saveUninitialized
113 +
114 + // get the cookie signing secret
115 + var secret = opts.secret
116 +
117 + if (typeof generateId !== 'function') {
118 + throw new TypeError('genid option must be a function');
119 + }
120 +
121 + if (resaveSession === undefined) {
122 + deprecate('undefined resave option; provide resave option');
123 + resaveSession = true;
124 + }
125 +
126 + if (saveUninitializedSession === undefined) {
127 + deprecate('undefined saveUninitialized option; provide saveUninitialized option');
128 + saveUninitializedSession = true;
129 + }
130 +
131 + if (opts.unset && opts.unset !== 'destroy' && opts.unset !== 'keep') {
132 + throw new TypeError('unset option must be "destroy" or "keep"');
133 + }
134 +
135 + // TODO: switch to "destroy" on next major
136 + var unsetDestroy = opts.unset === 'destroy'
137 +
138 + if (Array.isArray(secret) && secret.length === 0) {
139 + throw new TypeError('secret option array must contain one or more strings');
140 + }
141 +
142 + if (secret && !Array.isArray(secret)) {
143 + secret = [secret];
144 + }
145 +
146 + if (!secret) {
147 + deprecate('req.secret; provide secret option');
148 + }
149 +
150 + // notify user that this store is not
151 + // meant for a production environment
152 + /* istanbul ignore next: not tested */
153 + if (env === 'production' && store instanceof MemoryStore) {
154 + console.warn(warning);
155 + }
156 +
157 + // generates the new session
158 + store.generate = function(req){
159 + req.sessionID = generateId(req);
160 + req.session = new Session(req);
161 + req.session.cookie = new Cookie(cookieOptions);
162 +
163 + if (cookieOptions.secure === 'auto') {
164 + req.session.cookie.secure = issecure(req, trustProxy);
165 + }
166 + };
167 +
168 + var storeImplementsTouch = typeof store.touch === 'function';
169 +
170 + // register event listeners for the store to track readiness
171 + var storeReady = true
172 + store.on('disconnect', function ondisconnect() {
173 + storeReady = false
174 + })
175 + store.on('connect', function onconnect() {
176 + storeReady = true
177 + })
178 +
179 + return function session(req, res, next) {
180 + // self-awareness
181 + if (req.session) {
182 + next()
183 + return
184 + }
185 +
186 + // Handle connection as if there is no session if
187 + // the store has temporarily disconnected etc
188 + if (!storeReady) {
189 + debug('store is disconnected')
190 + next()
191 + return
192 + }
193 +
194 + // pathname mismatch
195 + var originalPath = parseUrl.original(req).pathname || '/'
196 + if (originalPath.indexOf(cookieOptions.path || '/') !== 0) return next();
197 +
198 + // ensure a secret is available or bail
199 + if (!secret && !req.secret) {
200 + next(new Error('secret option required for sessions'));
201 + return;
202 + }
203 +
204 + // backwards compatibility for signed cookies
205 + // req.secret is passed from the cookie parser middleware
206 + var secrets = secret || [req.secret];
207 +
208 + var originalHash;
209 + var originalId;
210 + var savedHash;
211 + var touched = false
212 +
213 + // expose store
214 + req.sessionStore = store;
215 +
216 + // get the session ID from the cookie
217 + var cookieId = req.sessionID = getcookie(req, name, secrets);
218 +
219 + // set-cookie
220 + onHeaders(res, function(){
221 + if (!req.session) {
222 + debug('no session');
223 + return;
224 + }
225 +
226 + if (!shouldSetCookie(req)) {
227 + return;
228 + }
229 +
230 + // only send secure cookies via https
231 + if (req.session.cookie.secure && !issecure(req, trustProxy)) {
232 + debug('not secured');
233 + return;
234 + }
235 +
236 + if (!touched) {
237 + // touch session
238 + req.session.touch()
239 + touched = true
240 + }
241 +
242 + // set cookie
243 + setcookie(res, name, req.sessionID, secrets[0], req.session.cookie.data);
244 + });
245 +
246 + // proxy end() to commit the session
247 + var _end = res.end;
248 + var _write = res.write;
249 + var ended = false;
250 + res.end = function end(chunk, encoding) {
251 + if (ended) {
252 + return false;
253 + }
254 +
255 + ended = true;
256 +
257 + var ret;
258 + var sync = true;
259 +
260 + function writeend() {
261 + if (sync) {
262 + ret = _end.call(res, chunk, encoding);
263 + sync = false;
264 + return;
265 + }
266 +
267 + _end.call(res);
268 + }
269 +
270 + function writetop() {
271 + if (!sync) {
272 + return ret;
273 + }
274 +
275 + if (chunk == null) {
276 + ret = true;
277 + return ret;
278 + }
279 +
280 + var contentLength = Number(res.getHeader('Content-Length'));
281 +
282 + if (!isNaN(contentLength) && contentLength > 0) {
283 + // measure chunk
284 + chunk = !Buffer.isBuffer(chunk)
285 + ? Buffer.from(chunk, encoding)
286 + : chunk;
287 + encoding = undefined;
288 +
289 + if (chunk.length !== 0) {
290 + debug('split response');
291 + ret = _write.call(res, chunk.slice(0, chunk.length - 1));
292 + chunk = chunk.slice(chunk.length - 1, chunk.length);
293 + return ret;
294 + }
295 + }
296 +
297 + ret = _write.call(res, chunk, encoding);
298 + sync = false;
299 +
300 + return ret;
301 + }
302 +
303 + if (shouldDestroy(req)) {
304 + // destroy session
305 + debug('destroying');
306 + store.destroy(req.sessionID, function ondestroy(err) {
307 + if (err) {
308 + defer(next, err);
309 + }
310 +
311 + debug('destroyed');
312 + writeend();
313 + });
314 +
315 + return writetop();
316 + }
317 +
318 + // no session to save
319 + if (!req.session) {
320 + debug('no session');
321 + return _end.call(res, chunk, encoding);
322 + }
323 +
324 + if (!touched) {
325 + // touch session
326 + req.session.touch()
327 + touched = true
328 + }
329 +
330 + if (shouldSave(req)) {
331 + req.session.save(function onsave(err) {
332 + if (err) {
333 + defer(next, err);
334 + }
335 +
336 + writeend();
337 + });
338 +
339 + return writetop();
340 + } else if (storeImplementsTouch && shouldTouch(req)) {
341 + // store implements touch method
342 + debug('touching');
343 + store.touch(req.sessionID, req.session, function ontouch(err) {
344 + if (err) {
345 + defer(next, err);
346 + }
347 +
348 + debug('touched');
349 + writeend();
350 + });
351 +
352 + return writetop();
353 + }
354 +
355 + return _end.call(res, chunk, encoding);
356 + };
357 +
358 + // generate the session
359 + function generate() {
360 + store.generate(req);
361 + originalId = req.sessionID;
362 + originalHash = hash(req.session);
363 + wrapmethods(req.session);
364 + }
365 +
366 + // inflate the session
367 + function inflate (req, sess) {
368 + store.createSession(req, sess)
369 + originalId = req.sessionID
370 + originalHash = hash(sess)
371 +
372 + if (!resaveSession) {
373 + savedHash = originalHash
374 + }
375 +
376 + wrapmethods(req.session)
377 + }
378 +
379 + function rewrapmethods (sess, callback) {
380 + return function () {
381 + if (req.session !== sess) {
382 + wrapmethods(req.session)
383 + }
384 +
385 + callback.apply(this, arguments)
386 + }
387 + }
388 +
389 + // wrap session methods
390 + function wrapmethods(sess) {
391 + var _reload = sess.reload
392 + var _save = sess.save;
393 +
394 + function reload(callback) {
395 + debug('reloading %s', this.id)
396 + _reload.call(this, rewrapmethods(this, callback))
397 + }
398 +
399 + function save() {
400 + debug('saving %s', this.id);
401 + savedHash = hash(this);
402 + _save.apply(this, arguments);
403 + }
404 +
405 + Object.defineProperty(sess, 'reload', {
406 + configurable: true,
407 + enumerable: false,
408 + value: reload,
409 + writable: true
410 + })
411 +
412 + Object.defineProperty(sess, 'save', {
413 + configurable: true,
414 + enumerable: false,
415 + value: save,
416 + writable: true
417 + });
418 + }
419 +
420 + // check if session has been modified
421 + function isModified(sess) {
422 + return originalId !== sess.id || originalHash !== hash(sess);
423 + }
424 +
425 + // check if session has been saved
426 + function isSaved(sess) {
427 + return originalId === sess.id && savedHash === hash(sess);
428 + }
429 +
430 + // determine if session should be destroyed
431 + function shouldDestroy(req) {
432 + return req.sessionID && unsetDestroy && req.session == null;
433 + }
434 +
435 + // determine if session should be saved to store
436 + function shouldSave(req) {
437 + // cannot set cookie without a session ID
438 + if (typeof req.sessionID !== 'string') {
439 + debug('session ignored because of bogus req.sessionID %o', req.sessionID);
440 + return false;
441 + }
442 +
443 + return !saveUninitializedSession && cookieId !== req.sessionID
444 + ? isModified(req.session)
445 + : !isSaved(req.session)
446 + }
447 +
448 + // determine if session should be touched
449 + function shouldTouch(req) {
450 + // cannot set cookie without a session ID
451 + if (typeof req.sessionID !== 'string') {
452 + debug('session ignored because of bogus req.sessionID %o', req.sessionID);
453 + return false;
454 + }
455 +
456 + return cookieId === req.sessionID && !shouldSave(req);
457 + }
458 +
459 + // determine if cookie should be set on response
460 + function shouldSetCookie(req) {
461 + // cannot set cookie without a session ID
462 + if (typeof req.sessionID !== 'string') {
463 + return false;
464 + }
465 +
466 + return cookieId !== req.sessionID
467 + ? saveUninitializedSession || isModified(req.session)
468 + : rollingSessions || req.session.cookie.expires != null && isModified(req.session);
469 + }
470 +
471 + // generate a session if the browser doesn't send a sessionID
472 + if (!req.sessionID) {
473 + debug('no SID sent, generating session');
474 + generate();
475 + next();
476 + return;
477 + }
478 +
479 + // generate the session object
480 + debug('fetching %s', req.sessionID);
481 + store.get(req.sessionID, function(err, sess){
482 + // error handling
483 + if (err && err.code !== 'ENOENT') {
484 + debug('error %j', err);
485 + next(err)
486 + return
487 + }
488 +
489 + try {
490 + if (err || !sess) {
491 + debug('no session found')
492 + generate()
493 + } else {
494 + debug('session found')
495 + inflate(req, sess)
496 + }
497 + } catch (e) {
498 + next(e)
499 + return
500 + }
501 +
502 + next()
503 + });
504 + };
505 +};
506 +
507 +/**
508 + * Generate a session ID for a new session.
509 + *
510 + * @return {String}
511 + * @private
512 + */
513 +
514 +function generateSessionId(sess) {
515 + return uid(24);
516 +}
517 +
518 +/**
519 + * Get the session ID cookie from request.
520 + *
521 + * @return {string}
522 + * @private
523 + */
524 +
525 +function getcookie(req, name, secrets) {
526 + var header = req.headers.cookie;
527 + var raw;
528 + var val;
529 +
530 + // read from cookie header
531 + if (header) {
532 + var cookies = cookie.parse(header);
533 +
534 + raw = cookies[name];
535 +
536 + if (raw) {
537 + if (raw.substr(0, 2) === 's:') {
538 + val = unsigncookie(raw.slice(2), secrets);
539 +
540 + if (val === false) {
541 + debug('cookie signature invalid');
542 + val = undefined;
543 + }
544 + } else {
545 + debug('cookie unsigned')
546 + }
547 + }
548 + }
549 +
550 + // back-compat read from cookieParser() signedCookies data
551 + if (!val && req.signedCookies) {
552 + val = req.signedCookies[name];
553 +
554 + if (val) {
555 + deprecate('cookie should be available in req.headers.cookie');
556 + }
557 + }
558 +
559 + // back-compat read from cookieParser() cookies data
560 + if (!val && req.cookies) {
561 + raw = req.cookies[name];
562 +
563 + if (raw) {
564 + if (raw.substr(0, 2) === 's:') {
565 + val = unsigncookie(raw.slice(2), secrets);
566 +
567 + if (val) {
568 + deprecate('cookie should be available in req.headers.cookie');
569 + }
570 +
571 + if (val === false) {
572 + debug('cookie signature invalid');
573 + val = undefined;
574 + }
575 + } else {
576 + debug('cookie unsigned')
577 + }
578 + }
579 + }
580 +
581 + return val;
582 +}
583 +
584 +/**
585 + * Hash the given `sess` object omitting changes to `.cookie`.
586 + *
587 + * @param {Object} sess
588 + * @return {String}
589 + * @private
590 + */
591 +
592 +function hash(sess) {
593 + // serialize
594 + var str = JSON.stringify(sess, function (key, val) {
595 + // ignore sess.cookie property
596 + if (this === sess && key === 'cookie') {
597 + return
598 + }
599 +
600 + return val
601 + })
602 +
603 + // hash
604 + return crypto
605 + .createHash('sha1')
606 + .update(str, 'utf8')
607 + .digest('hex')
608 +}
609 +
610 +/**
611 + * Determine if request is secure.
612 + *
613 + * @param {Object} req
614 + * @param {Boolean} [trustProxy]
615 + * @return {Boolean}
616 + * @private
617 + */
618 +
619 +function issecure(req, trustProxy) {
620 + // socket is https server
621 + if (req.connection && req.connection.encrypted) {
622 + return true;
623 + }
624 +
625 + // do not trust proxy
626 + if (trustProxy === false) {
627 + return false;
628 + }
629 +
630 + // no explicit trust; try req.secure from express
631 + if (trustProxy !== true) {
632 + return req.secure === true
633 + }
634 +
635 + // read the proto from x-forwarded-proto header
636 + var header = req.headers['x-forwarded-proto'] || '';
637 + var index = header.indexOf(',');
638 + var proto = index !== -1
639 + ? header.substr(0, index).toLowerCase().trim()
640 + : header.toLowerCase().trim()
641 +
642 + return proto === 'https';
643 +}
644 +
645 +/**
646 + * Set cookie on response.
647 + *
648 + * @private
649 + */
650 +
651 +function setcookie(res, name, val, secret, options) {
652 + var signed = 's:' + signature.sign(val, secret);
653 + var data = cookie.serialize(name, signed, options);
654 +
655 + debug('set-cookie %s', data);
656 +
657 + var prev = res.getHeader('Set-Cookie') || []
658 + var header = Array.isArray(prev) ? prev.concat(data) : [prev, data];
659 +
660 + res.setHeader('Set-Cookie', header)
661 +}
662 +
663 +/**
664 + * Verify and decode the given `val` with `secrets`.
665 + *
666 + * @param {String} val
667 + * @param {Array} secrets
668 + * @returns {String|Boolean}
669 + * @private
670 + */
671 +function unsigncookie(val, secrets) {
672 + for (var i = 0; i < secrets.length; i++) {
673 + var result = signature.unsign(val, secrets[i]);
674 +
675 + if (result !== false) {
676 + return result;
677 + }
678 + }
679 +
680 + return false;
681 +}
1 +2.0.0 / 2018-10-26
2 +==================
3 +
4 + * Drop support for Node.js 0.6
5 + * Replace internal `eval` usage with `Function` constructor
6 + * Use instance methods on `process` to check for listeners
7 +
8 +1.1.2 / 2018-01-11
9 +==================
10 +
11 + * perf: remove argument reassignment
12 + * Support Node.js 0.6 to 9.x
13 +
14 +1.1.1 / 2017-07-27
15 +==================
16 +
17 + * Remove unnecessary `Buffer` loading
18 + * Support Node.js 0.6 to 8.x
19 +
20 +1.1.0 / 2015-09-14
21 +==================
22 +
23 + * Enable strict mode in more places
24 + * Support io.js 3.x
25 + * Support io.js 2.x
26 + * Support web browser loading
27 + - Requires bundler like Browserify or webpack
28 +
29 +1.0.1 / 2015-04-07
30 +==================
31 +
32 + * Fix `TypeError`s when under `'use strict'` code
33 + * Fix useless type name on auto-generated messages
34 + * Support io.js 1.x
35 + * Support Node.js 0.12
36 +
37 +1.0.0 / 2014-09-17
38 +==================
39 +
40 + * No changes
41 +
42 +0.4.5 / 2014-09-09
43 +==================
44 +
45 + * Improve call speed to functions using the function wrapper
46 + * Support Node.js 0.6
47 +
48 +0.4.4 / 2014-07-27
49 +==================
50 +
51 + * Work-around v8 generating empty stack traces
52 +
53 +0.4.3 / 2014-07-26
54 +==================
55 +
56 + * Fix exception when global `Error.stackTraceLimit` is too low
57 +
58 +0.4.2 / 2014-07-19
59 +==================
60 +
61 + * Correct call site for wrapped functions and properties
62 +
63 +0.4.1 / 2014-07-19
64 +==================
65 +
66 + * Improve automatic message generation for function properties
67 +
68 +0.4.0 / 2014-07-19
69 +==================
70 +
71 + * Add `TRACE_DEPRECATION` environment variable
72 + * Remove non-standard grey color from color output
73 + * Support `--no-deprecation` argument
74 + * Support `--trace-deprecation` argument
75 + * Support `deprecate.property(fn, prop, message)`
76 +
77 +0.3.0 / 2014-06-16
78 +==================
79 +
80 + * Add `NO_DEPRECATION` environment variable
81 +
82 +0.2.0 / 2014-06-15
83 +==================
84 +
85 + * Add `deprecate.property(obj, prop, message)`
86 + * Remove `supports-color` dependency for node.js 0.8
87 +
88 +0.1.0 / 2014-06-15
89 +==================
90 +
91 + * Add `deprecate.function(fn, message)`
92 + * Add `process.on('deprecation', fn)` emitter
93 + * Automatically generate message when omitted from `deprecate()`
94 +
95 +0.0.1 / 2014-06-15
96 +==================
97 +
98 + * Fix warning for dynamic calls at singe call site
99 +
100 +0.0.0 / 2014-06-15
101 +==================
102 +
103 + * Initial implementation
1 +(The MIT License)
2 +
3 +Copyright (c) 2014-2018 Douglas Christopher Wilson
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining
6 +a copy of this software and associated documentation files (the
7 +'Software'), to deal in the Software without restriction, including
8 +without limitation the rights to use, copy, modify, merge, publish,
9 +distribute, sublicense, and/or sell copies of the Software, and to
10 +permit persons to whom the Software is furnished to do so, subject to
11 +the following conditions:
12 +
13 +The above copyright notice and this permission notice shall be
14 +included in all copies or substantial portions of the Software.
15 +
16 +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 +# depd
2 +
3 +[![NPM Version][npm-version-image]][npm-url]
4 +[![NPM Downloads][npm-downloads-image]][npm-url]
5 +[![Node.js Version][node-image]][node-url]
6 +[![Linux Build][travis-image]][travis-url]
7 +[![Windows Build][appveyor-image]][appveyor-url]
8 +[![Coverage Status][coveralls-image]][coveralls-url]
9 +
10 +Deprecate all the things
11 +
12 +> With great modules comes great responsibility; mark things deprecated!
13 +
14 +## Install
15 +
16 +This module is installed directly using `npm`:
17 +
18 +```sh
19 +$ npm install depd
20 +```
21 +
22 +This module can also be bundled with systems like
23 +[Browserify](http://browserify.org/) or [webpack](https://webpack.github.io/),
24 +though by default this module will alter it's API to no longer display or
25 +track deprecations.
26 +
27 +## API
28 +
29 +<!-- eslint-disable no-unused-vars -->
30 +
31 +```js
32 +var deprecate = require('depd')('my-module')
33 +```
34 +
35 +This library allows you to display deprecation messages to your users.
36 +This library goes above and beyond with deprecation warnings by
37 +introspection of the call stack (but only the bits that it is interested
38 +in).
39 +
40 +Instead of just warning on the first invocation of a deprecated
41 +function and never again, this module will warn on the first invocation
42 +of a deprecated function per unique call site, making it ideal to alert
43 +users of all deprecated uses across the code base, rather than just
44 +whatever happens to execute first.
45 +
46 +The deprecation warnings from this module also include the file and line
47 +information for the call into the module that the deprecated function was
48 +in.
49 +
50 +**NOTE** this library has a similar interface to the `debug` module, and
51 +this module uses the calling file to get the boundary for the call stacks,
52 +so you should always create a new `deprecate` object in each file and not
53 +within some central file.
54 +
55 +### depd(namespace)
56 +
57 +Create a new deprecate function that uses the given namespace name in the
58 +messages and will display the call site prior to the stack entering the
59 +file this function was called from. It is highly suggested you use the
60 +name of your module as the namespace.
61 +
62 +### deprecate(message)
63 +
64 +Call this function from deprecated code to display a deprecation message.
65 +This message will appear once per unique caller site. Caller site is the
66 +first call site in the stack in a different file from the caller of this
67 +function.
68 +
69 +If the message is omitted, a message is generated for you based on the site
70 +of the `deprecate()` call and will display the name of the function called,
71 +similar to the name displayed in a stack trace.
72 +
73 +### deprecate.function(fn, message)
74 +
75 +Call this function to wrap a given function in a deprecation message on any
76 +call to the function. An optional message can be supplied to provide a custom
77 +message.
78 +
79 +### deprecate.property(obj, prop, message)
80 +
81 +Call this function to wrap a given property on object in a deprecation message
82 +on any accessing or setting of the property. An optional message can be supplied
83 +to provide a custom message.
84 +
85 +The method must be called on the object where the property belongs (not
86 +inherited from the prototype).
87 +
88 +If the property is a data descriptor, it will be converted to an accessor
89 +descriptor in order to display the deprecation message.
90 +
91 +### process.on('deprecation', fn)
92 +
93 +This module will allow easy capturing of deprecation errors by emitting the
94 +errors as the type "deprecation" on the global `process`. If there are no
95 +listeners for this type, the errors are written to STDERR as normal, but if
96 +there are any listeners, nothing will be written to STDERR and instead only
97 +emitted. From there, you can write the errors in a different format or to a
98 +logging source.
99 +
100 +The error represents the deprecation and is emitted only once with the same
101 +rules as writing to STDERR. The error has the following properties:
102 +
103 + - `message` - This is the message given by the library
104 + - `name` - This is always `'DeprecationError'`
105 + - `namespace` - This is the namespace the deprecation came from
106 + - `stack` - This is the stack of the call to the deprecated thing
107 +
108 +Example `error.stack` output:
109 +
110 +```
111 +DeprecationError: my-cool-module deprecated oldfunction
112 + at Object.<anonymous> ([eval]-wrapper:6:22)
113 + at Module._compile (module.js:456:26)
114 + at evalScript (node.js:532:25)
115 + at startup (node.js:80:7)
116 + at node.js:902:3
117 +```
118 +
119 +### process.env.NO_DEPRECATION
120 +
121 +As a user of modules that are deprecated, the environment variable `NO_DEPRECATION`
122 +is provided as a quick solution to silencing deprecation warnings from being
123 +output. The format of this is similar to that of `DEBUG`:
124 +
125 +```sh
126 +$ NO_DEPRECATION=my-module,othermod node app.js
127 +```
128 +
129 +This will suppress deprecations from being output for "my-module" and "othermod".
130 +The value is a list of comma-separated namespaces. To suppress every warning
131 +across all namespaces, use the value `*` for a namespace.
132 +
133 +Providing the argument `--no-deprecation` to the `node` executable will suppress
134 +all deprecations (only available in Node.js 0.8 or higher).
135 +
136 +**NOTE** This will not suppress the deperecations given to any "deprecation"
137 +event listeners, just the output to STDERR.
138 +
139 +### process.env.TRACE_DEPRECATION
140 +
141 +As a user of modules that are deprecated, the environment variable `TRACE_DEPRECATION`
142 +is provided as a solution to getting more detailed location information in deprecation
143 +warnings by including the entire stack trace. The format of this is the same as
144 +`NO_DEPRECATION`:
145 +
146 +```sh
147 +$ TRACE_DEPRECATION=my-module,othermod node app.js
148 +```
149 +
150 +This will include stack traces for deprecations being output for "my-module" and
151 +"othermod". The value is a list of comma-separated namespaces. To trace every
152 +warning across all namespaces, use the value `*` for a namespace.
153 +
154 +Providing the argument `--trace-deprecation` to the `node` executable will trace
155 +all deprecations (only available in Node.js 0.8 or higher).
156 +
157 +**NOTE** This will not trace the deperecations silenced by `NO_DEPRECATION`.
158 +
159 +## Display
160 +
161 +![message](files/message.png)
162 +
163 +When a user calls a function in your library that you mark deprecated, they
164 +will see the following written to STDERR (in the given colors, similar colors
165 +and layout to the `debug` module):
166 +
167 +```
168 +bright cyan bright yellow
169 +| | reset cyan
170 +| | | |
171 +▼ ▼ ▼ ▼
172 +my-cool-module deprecated oldfunction [eval]-wrapper:6:22
173 +▲ ▲ ▲ ▲
174 +| | | |
175 +namespace | | location of mycoolmod.oldfunction() call
176 + | deprecation message
177 + the word "deprecated"
178 +```
179 +
180 +If the user redirects their STDERR to a file or somewhere that does not support
181 +colors, they see (similar layout to the `debug` module):
182 +
183 +```
184 +Sun, 15 Jun 2014 05:21:37 GMT my-cool-module deprecated oldfunction at [eval]-wrapper:6:22
185 +▲ ▲ ▲ ▲ ▲
186 +| | | | |
187 +timestamp of message namespace | | location of mycoolmod.oldfunction() call
188 + | deprecation message
189 + the word "deprecated"
190 +```
191 +
192 +## Examples
193 +
194 +### Deprecating all calls to a function
195 +
196 +This will display a deprecated message about "oldfunction" being deprecated
197 +from "my-module" on STDERR.
198 +
199 +```js
200 +var deprecate = require('depd')('my-cool-module')
201 +
202 +// message automatically derived from function name
203 +// Object.oldfunction
204 +exports.oldfunction = deprecate.function(function oldfunction () {
205 + // all calls to function are deprecated
206 +})
207 +
208 +// specific message
209 +exports.oldfunction = deprecate.function(function () {
210 + // all calls to function are deprecated
211 +}, 'oldfunction')
212 +```
213 +
214 +### Conditionally deprecating a function call
215 +
216 +This will display a deprecated message about "weirdfunction" being deprecated
217 +from "my-module" on STDERR when called with less than 2 arguments.
218 +
219 +```js
220 +var deprecate = require('depd')('my-cool-module')
221 +
222 +exports.weirdfunction = function () {
223 + if (arguments.length < 2) {
224 + // calls with 0 or 1 args are deprecated
225 + deprecate('weirdfunction args < 2')
226 + }
227 +}
228 +```
229 +
230 +When calling `deprecate` as a function, the warning is counted per call site
231 +within your own module, so you can display different deprecations depending
232 +on different situations and the users will still get all the warnings:
233 +
234 +```js
235 +var deprecate = require('depd')('my-cool-module')
236 +
237 +exports.weirdfunction = function () {
238 + if (arguments.length < 2) {
239 + // calls with 0 or 1 args are deprecated
240 + deprecate('weirdfunction args < 2')
241 + } else if (typeof arguments[0] !== 'string') {
242 + // calls with non-string first argument are deprecated
243 + deprecate('weirdfunction non-string first arg')
244 + }
245 +}
246 +```
247 +
248 +### Deprecating property access
249 +
250 +This will display a deprecated message about "oldprop" being deprecated
251 +from "my-module" on STDERR when accessed. A deprecation will be displayed
252 +when setting the value and when getting the value.
253 +
254 +```js
255 +var deprecate = require('depd')('my-cool-module')
256 +
257 +exports.oldprop = 'something'
258 +
259 +// message automatically derives from property name
260 +deprecate.property(exports, 'oldprop')
261 +
262 +// explicit message
263 +deprecate.property(exports, 'oldprop', 'oldprop >= 0.10')
264 +```
265 +
266 +## License
267 +
268 +[MIT](LICENSE)
269 +
270 +[appveyor-image]: https://badgen.net/appveyor/ci/dougwilson/nodejs-depd/master?label=windows
271 +[appveyor-url]: https://ci.appveyor.com/project/dougwilson/nodejs-depd
272 +[coveralls-image]: https://badgen.net/coveralls/c/github/dougwilson/nodejs-depd/master
273 +[coveralls-url]: https://coveralls.io/r/dougwilson/nodejs-depd?branch=master
274 +[node-image]: https://badgen.net/npm/node/depd
275 +[node-url]: https://nodejs.org/en/download/
276 +[npm-downloads-image]: https://badgen.net/npm/dm/depd
277 +[npm-url]: https://npmjs.org/package/depd
278 +[npm-version-image]: https://badgen.net/npm/v/depd
279 +[travis-image]: https://badgen.net/travis/dougwilson/nodejs-depd/master?label=linux
280 +[travis-url]: https://travis-ci.org/dougwilson/nodejs-depd
1 +/*!
2 + * depd
3 + * Copyright(c) 2014-2018 Douglas Christopher Wilson
4 + * MIT Licensed
5 + */
6 +
7 +/**
8 + * Module dependencies.
9 + */
10 +
11 +var relative = require('path').relative
12 +
13 +/**
14 + * Module exports.
15 + */
16 +
17 +module.exports = depd
18 +
19 +/**
20 + * Get the path to base files on.
21 + */
22 +
23 +var basePath = process.cwd()
24 +
25 +/**
26 + * Determine if namespace is contained in the string.
27 + */
28 +
29 +function containsNamespace (str, namespace) {
30 + var vals = str.split(/[ ,]+/)
31 + var ns = String(namespace).toLowerCase()
32 +
33 + for (var i = 0; i < vals.length; i++) {
34 + var val = vals[i]
35 +
36 + // namespace contained
37 + if (val && (val === '*' || val.toLowerCase() === ns)) {
38 + return true
39 + }
40 + }
41 +
42 + return false
43 +}
44 +
45 +/**
46 + * Convert a data descriptor to accessor descriptor.
47 + */
48 +
49 +function convertDataDescriptorToAccessor (obj, prop, message) {
50 + var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
51 + var value = descriptor.value
52 +
53 + descriptor.get = function getter () { return value }
54 +
55 + if (descriptor.writable) {
56 + descriptor.set = function setter (val) { return (value = val) }
57 + }
58 +
59 + delete descriptor.value
60 + delete descriptor.writable
61 +
62 + Object.defineProperty(obj, prop, descriptor)
63 +
64 + return descriptor
65 +}
66 +
67 +/**
68 + * Create arguments string to keep arity.
69 + */
70 +
71 +function createArgumentsString (arity) {
72 + var str = ''
73 +
74 + for (var i = 0; i < arity; i++) {
75 + str += ', arg' + i
76 + }
77 +
78 + return str.substr(2)
79 +}
80 +
81 +/**
82 + * Create stack string from stack.
83 + */
84 +
85 +function createStackString (stack) {
86 + var str = this.name + ': ' + this.namespace
87 +
88 + if (this.message) {
89 + str += ' deprecated ' + this.message
90 + }
91 +
92 + for (var i = 0; i < stack.length; i++) {
93 + str += '\n at ' + stack[i].toString()
94 + }
95 +
96 + return str
97 +}
98 +
99 +/**
100 + * Create deprecate for namespace in caller.
101 + */
102 +
103 +function depd (namespace) {
104 + if (!namespace) {
105 + throw new TypeError('argument namespace is required')
106 + }
107 +
108 + var stack = getStack()
109 + var site = callSiteLocation(stack[1])
110 + var file = site[0]
111 +
112 + function deprecate (message) {
113 + // call to self as log
114 + log.call(deprecate, message)
115 + }
116 +
117 + deprecate._file = file
118 + deprecate._ignored = isignored(namespace)
119 + deprecate._namespace = namespace
120 + deprecate._traced = istraced(namespace)
121 + deprecate._warned = Object.create(null)
122 +
123 + deprecate.function = wrapfunction
124 + deprecate.property = wrapproperty
125 +
126 + return deprecate
127 +}
128 +
129 +/**
130 + * Determine if event emitter has listeners of a given type.
131 + *
132 + * The way to do this check is done three different ways in Node.js >= 0.8
133 + * so this consolidates them into a minimal set using instance methods.
134 + *
135 + * @param {EventEmitter} emitter
136 + * @param {string} type
137 + * @returns {boolean}
138 + * @private
139 + */
140 +
141 +function eehaslisteners (emitter, type) {
142 + var count = typeof emitter.listenerCount !== 'function'
143 + ? emitter.listeners(type).length
144 + : emitter.listenerCount(type)
145 +
146 + return count > 0
147 +}
148 +
149 +/**
150 + * Determine if namespace is ignored.
151 + */
152 +
153 +function isignored (namespace) {
154 + if (process.noDeprecation) {
155 + // --no-deprecation support
156 + return true
157 + }
158 +
159 + var str = process.env.NO_DEPRECATION || ''
160 +
161 + // namespace ignored
162 + return containsNamespace(str, namespace)
163 +}
164 +
165 +/**
166 + * Determine if namespace is traced.
167 + */
168 +
169 +function istraced (namespace) {
170 + if (process.traceDeprecation) {
171 + // --trace-deprecation support
172 + return true
173 + }
174 +
175 + var str = process.env.TRACE_DEPRECATION || ''
176 +
177 + // namespace traced
178 + return containsNamespace(str, namespace)
179 +}
180 +
181 +/**
182 + * Display deprecation message.
183 + */
184 +
185 +function log (message, site) {
186 + var haslisteners = eehaslisteners(process, 'deprecation')
187 +
188 + // abort early if no destination
189 + if (!haslisteners && this._ignored) {
190 + return
191 + }
192 +
193 + var caller
194 + var callFile
195 + var callSite
196 + var depSite
197 + var i = 0
198 + var seen = false
199 + var stack = getStack()
200 + var file = this._file
201 +
202 + if (site) {
203 + // provided site
204 + depSite = site
205 + callSite = callSiteLocation(stack[1])
206 + callSite.name = depSite.name
207 + file = callSite[0]
208 + } else {
209 + // get call site
210 + i = 2
211 + depSite = callSiteLocation(stack[i])
212 + callSite = depSite
213 + }
214 +
215 + // get caller of deprecated thing in relation to file
216 + for (; i < stack.length; i++) {
217 + caller = callSiteLocation(stack[i])
218 + callFile = caller[0]
219 +
220 + if (callFile === file) {
221 + seen = true
222 + } else if (callFile === this._file) {
223 + file = this._file
224 + } else if (seen) {
225 + break
226 + }
227 + }
228 +
229 + var key = caller
230 + ? depSite.join(':') + '__' + caller.join(':')
231 + : undefined
232 +
233 + if (key !== undefined && key in this._warned) {
234 + // already warned
235 + return
236 + }
237 +
238 + this._warned[key] = true
239 +
240 + // generate automatic message from call site
241 + var msg = message
242 + if (!msg) {
243 + msg = callSite === depSite || !callSite.name
244 + ? defaultMessage(depSite)
245 + : defaultMessage(callSite)
246 + }
247 +
248 + // emit deprecation if listeners exist
249 + if (haslisteners) {
250 + var err = DeprecationError(this._namespace, msg, stack.slice(i))
251 + process.emit('deprecation', err)
252 + return
253 + }
254 +
255 + // format and write message
256 + var format = process.stderr.isTTY
257 + ? formatColor
258 + : formatPlain
259 + var output = format.call(this, msg, caller, stack.slice(i))
260 + process.stderr.write(output + '\n', 'utf8')
261 +}
262 +
263 +/**
264 + * Get call site location as array.
265 + */
266 +
267 +function callSiteLocation (callSite) {
268 + var file = callSite.getFileName() || '<anonymous>'
269 + var line = callSite.getLineNumber()
270 + var colm = callSite.getColumnNumber()
271 +
272 + if (callSite.isEval()) {
273 + file = callSite.getEvalOrigin() + ', ' + file
274 + }
275 +
276 + var site = [file, line, colm]
277 +
278 + site.callSite = callSite
279 + site.name = callSite.getFunctionName()
280 +
281 + return site
282 +}
283 +
284 +/**
285 + * Generate a default message from the site.
286 + */
287 +
288 +function defaultMessage (site) {
289 + var callSite = site.callSite
290 + var funcName = site.name
291 +
292 + // make useful anonymous name
293 + if (!funcName) {
294 + funcName = '<anonymous@' + formatLocation(site) + '>'
295 + }
296 +
297 + var context = callSite.getThis()
298 + var typeName = context && callSite.getTypeName()
299 +
300 + // ignore useless type name
301 + if (typeName === 'Object') {
302 + typeName = undefined
303 + }
304 +
305 + // make useful type name
306 + if (typeName === 'Function') {
307 + typeName = context.name || typeName
308 + }
309 +
310 + return typeName && callSite.getMethodName()
311 + ? typeName + '.' + funcName
312 + : funcName
313 +}
314 +
315 +/**
316 + * Format deprecation message without color.
317 + */
318 +
319 +function formatPlain (msg, caller, stack) {
320 + var timestamp = new Date().toUTCString()
321 +
322 + var formatted = timestamp +
323 + ' ' + this._namespace +
324 + ' deprecated ' + msg
325 +
326 + // add stack trace
327 + if (this._traced) {
328 + for (var i = 0; i < stack.length; i++) {
329 + formatted += '\n at ' + stack[i].toString()
330 + }
331 +
332 + return formatted
333 + }
334 +
335 + if (caller) {
336 + formatted += ' at ' + formatLocation(caller)
337 + }
338 +
339 + return formatted
340 +}
341 +
342 +/**
343 + * Format deprecation message with color.
344 + */
345 +
346 +function formatColor (msg, caller, stack) {
347 + var formatted = '\x1b[36;1m' + this._namespace + '\x1b[22;39m' + // bold cyan
348 + ' \x1b[33;1mdeprecated\x1b[22;39m' + // bold yellow
349 + ' \x1b[0m' + msg + '\x1b[39m' // reset
350 +
351 + // add stack trace
352 + if (this._traced) {
353 + for (var i = 0; i < stack.length; i++) {
354 + formatted += '\n \x1b[36mat ' + stack[i].toString() + '\x1b[39m' // cyan
355 + }
356 +
357 + return formatted
358 + }
359 +
360 + if (caller) {
361 + formatted += ' \x1b[36m' + formatLocation(caller) + '\x1b[39m' // cyan
362 + }
363 +
364 + return formatted
365 +}
366 +
367 +/**
368 + * Format call site location.
369 + */
370 +
371 +function formatLocation (callSite) {
372 + return relative(basePath, callSite[0]) +
373 + ':' + callSite[1] +
374 + ':' + callSite[2]
375 +}
376 +
377 +/**
378 + * Get the stack as array of call sites.
379 + */
380 +
381 +function getStack () {
382 + var limit = Error.stackTraceLimit
383 + var obj = {}
384 + var prep = Error.prepareStackTrace
385 +
386 + Error.prepareStackTrace = prepareObjectStackTrace
387 + Error.stackTraceLimit = Math.max(10, limit)
388 +
389 + // capture the stack
390 + Error.captureStackTrace(obj)
391 +
392 + // slice this function off the top
393 + var stack = obj.stack.slice(1)
394 +
395 + Error.prepareStackTrace = prep
396 + Error.stackTraceLimit = limit
397 +
398 + return stack
399 +}
400 +
401 +/**
402 + * Capture call site stack from v8.
403 + */
404 +
405 +function prepareObjectStackTrace (obj, stack) {
406 + return stack
407 +}
408 +
409 +/**
410 + * Return a wrapped function in a deprecation message.
411 + */
412 +
413 +function wrapfunction (fn, message) {
414 + if (typeof fn !== 'function') {
415 + throw new TypeError('argument fn must be a function')
416 + }
417 +
418 + var args = createArgumentsString(fn.length)
419 + var stack = getStack()
420 + var site = callSiteLocation(stack[1])
421 +
422 + site.name = fn.name
423 +
424 + // eslint-disable-next-line no-new-func
425 + var deprecatedfn = new Function('fn', 'log', 'deprecate', 'message', 'site',
426 + '"use strict"\n' +
427 + 'return function (' + args + ') {' +
428 + 'log.call(deprecate, message, site)\n' +
429 + 'return fn.apply(this, arguments)\n' +
430 + '}')(fn, log, this, message, site)
431 +
432 + return deprecatedfn
433 +}
434 +
435 +/**
436 + * Wrap property in a deprecation message.
437 + */
438 +
439 +function wrapproperty (obj, prop, message) {
440 + if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) {
441 + throw new TypeError('argument obj must be object')
442 + }
443 +
444 + var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
445 +
446 + if (!descriptor) {
447 + throw new TypeError('must call property on owner object')
448 + }
449 +
450 + if (!descriptor.configurable) {
451 + throw new TypeError('property must be configurable')
452 + }
453 +
454 + var deprecate = this
455 + var stack = getStack()
456 + var site = callSiteLocation(stack[1])
457 +
458 + // set site name
459 + site.name = prop
460 +
461 + // convert data descriptor
462 + if ('value' in descriptor) {
463 + descriptor = convertDataDescriptorToAccessor(obj, prop, message)
464 + }
465 +
466 + var get = descriptor.get
467 + var set = descriptor.set
468 +
469 + // wrap getter
470 + if (typeof get === 'function') {
471 + descriptor.get = function getter () {
472 + log.call(deprecate, message, site)
473 + return get.apply(this, arguments)
474 + }
475 + }
476 +
477 + // wrap setter
478 + if (typeof set === 'function') {
479 + descriptor.set = function setter () {
480 + log.call(deprecate, message, site)
481 + return set.apply(this, arguments)
482 + }
483 + }
484 +
485 + Object.defineProperty(obj, prop, descriptor)
486 +}
487 +
488 +/**
489 + * Create DeprecationError for deprecation
490 + */
491 +
492 +function DeprecationError (namespace, message, stack) {
493 + var error = new Error()
494 + var stackString
495 +
496 + Object.defineProperty(error, 'constructor', {
497 + value: DeprecationError
498 + })
499 +
500 + Object.defineProperty(error, 'message', {
501 + configurable: true,
502 + enumerable: false,
503 + value: message,
504 + writable: true
505 + })
506 +
507 + Object.defineProperty(error, 'name', {
508 + enumerable: false,
509 + configurable: true,
510 + value: 'DeprecationError',
511 + writable: true
512 + })
513 +
514 + Object.defineProperty(error, 'namespace', {
515 + configurable: true,
516 + enumerable: false,
517 + value: namespace,
518 + writable: true
519 + })
520 +
521 + Object.defineProperty(error, 'stack', {
522 + configurable: true,
523 + enumerable: false,
524 + get: function () {
525 + if (stackString !== undefined) {
526 + return stackString
527 + }
528 +
529 + // prepare stack trace
530 + return (stackString = createStackString.call(this, stack))
531 + },
532 + set: function setter (val) {
533 + stackString = val
534 + }
535 + })
536 +
537 + return error
538 +}
1 +/*!
2 + * depd
3 + * Copyright(c) 2015 Douglas Christopher Wilson
4 + * MIT Licensed
5 + */
6 +
7 +'use strict'
8 +
9 +/**
10 + * Module exports.
11 + * @public
12 + */
13 +
14 +module.exports = depd
15 +
16 +/**
17 + * Create deprecate for namespace in caller.
18 + */
19 +
20 +function depd (namespace) {
21 + if (!namespace) {
22 + throw new TypeError('argument namespace is required')
23 + }
24 +
25 + function deprecate (message) {
26 + // no-op in browser
27 + }
28 +
29 + deprecate._file = undefined
30 + deprecate._ignored = true
31 + deprecate._namespace = namespace
32 + deprecate._traced = false
33 + deprecate._warned = Object.create(null)
34 +
35 + deprecate.function = wrapfunction
36 + deprecate.property = wrapproperty
37 +
38 + return deprecate
39 +}
40 +
41 +/**
42 + * Return a wrapped function in a deprecation message.
43 + *
44 + * This is a no-op version of the wrapper, which does nothing but call
45 + * validation.
46 + */
47 +
48 +function wrapfunction (fn, message) {
49 + if (typeof fn !== 'function') {
50 + throw new TypeError('argument fn must be a function')
51 + }
52 +
53 + return fn
54 +}
55 +
56 +/**
57 + * Wrap property in a deprecation message.
58 + *
59 + * This is a no-op version of the wrapper, which does nothing but call
60 + * validation.
61 + */
62 +
63 +function wrapproperty (obj, prop, message) {
64 + if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) {
65 + throw new TypeError('argument obj must be object')
66 + }
67 +
68 + var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
69 +
70 + if (!descriptor) {
71 + throw new TypeError('must call property on owner object')
72 + }
73 +
74 + if (!descriptor.configurable) {
75 + throw new TypeError('property must be configurable')
76 + }
77 +}
1 +{
2 + "_from": "depd@~2.0.0",
3 + "_id": "depd@2.0.0",
4 + "_inBundle": false,
5 + "_integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
6 + "_location": "/express-session/depd",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "depd@~2.0.0",
12 + "name": "depd",
13 + "escapedName": "depd",
14 + "rawSpec": "~2.0.0",
15 + "saveSpec": null,
16 + "fetchSpec": "~2.0.0"
17 + },
18 + "_requiredBy": [
19 + "/express-session"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
22 + "_shasum": "b696163cc757560d09cf22cc8fad1571b79e76df",
23 + "_spec": "depd@~2.0.0",
24 + "_where": "C:\\Users\\fheld\\Desktop\\khuhub\\mapmory\\Mapmory\\node_modules\\express-session",
25 + "author": {
26 + "name": "Douglas Christopher Wilson",
27 + "email": "doug@somethingdoug.com"
28 + },
29 + "browser": "lib/browser/index.js",
30 + "bugs": {
31 + "url": "https://github.com/dougwilson/nodejs-depd/issues"
32 + },
33 + "bundleDependencies": false,
34 + "deprecated": false,
35 + "description": "Deprecate all the things",
36 + "devDependencies": {
37 + "beautify-benchmark": "0.2.4",
38 + "benchmark": "2.1.4",
39 + "eslint": "5.7.0",
40 + "eslint-config-standard": "12.0.0",
41 + "eslint-plugin-import": "2.14.0",
42 + "eslint-plugin-markdown": "1.0.0-beta.7",
43 + "eslint-plugin-node": "7.0.1",
44 + "eslint-plugin-promise": "4.0.1",
45 + "eslint-plugin-standard": "4.0.0",
46 + "istanbul": "0.4.5",
47 + "mocha": "5.2.0",
48 + "safe-buffer": "5.1.2",
49 + "uid-safe": "2.1.5"
50 + },
51 + "engines": {
52 + "node": ">= 0.8"
53 + },
54 + "files": [
55 + "lib/",
56 + "History.md",
57 + "LICENSE",
58 + "index.js",
59 + "Readme.md"
60 + ],
61 + "homepage": "https://github.com/dougwilson/nodejs-depd#readme",
62 + "keywords": [
63 + "deprecate",
64 + "deprecated"
65 + ],
66 + "license": "MIT",
67 + "name": "depd",
68 + "repository": {
69 + "type": "git",
70 + "url": "git+https://github.com/dougwilson/nodejs-depd.git"
71 + },
72 + "scripts": {
73 + "bench": "node benchmark/index.js",
74 + "lint": "eslint --plugin markdown --ext js,md .",
75 + "test": "mocha --reporter spec --bail test/",
76 + "test-ci": "istanbul cover --print=none node_modules/mocha/bin/_mocha -- --reporter spec test/ && istanbul report lcovonly text-summary",
77 + "test-cov": "istanbul cover --print=none node_modules/mocha/bin/_mocha -- --reporter dot test/ && istanbul report lcov text-summary"
78 + },
79 + "version": "2.0.0"
80 +}
1 +The MIT License (MIT)
2 +
3 +Copyright (c) Feross Aboukhadijeh
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +# safe-buffer [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url]
2 +
3 +[travis-image]: https://img.shields.io/travis/feross/safe-buffer/master.svg
4 +[travis-url]: https://travis-ci.org/feross/safe-buffer
5 +[npm-image]: https://img.shields.io/npm/v/safe-buffer.svg
6 +[npm-url]: https://npmjs.org/package/safe-buffer
7 +[downloads-image]: https://img.shields.io/npm/dm/safe-buffer.svg
8 +[downloads-url]: https://npmjs.org/package/safe-buffer
9 +[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg
10 +[standard-url]: https://standardjs.com
11 +
12 +#### Safer Node.js Buffer API
13 +
14 +**Use the new Node.js Buffer APIs (`Buffer.from`, `Buffer.alloc`,
15 +`Buffer.allocUnsafe`, `Buffer.allocUnsafeSlow`) in all versions of Node.js.**
16 +
17 +**Uses the built-in implementation when available.**
18 +
19 +## install
20 +
21 +```
22 +npm install safe-buffer
23 +```
24 +
25 +[Get supported safe-buffer with the Tidelift Subscription](https://tidelift.com/subscription/pkg/npm-safe-buffer?utm_source=npm-safe-buffer&utm_medium=referral&utm_campaign=readme)
26 +
27 +## usage
28 +
29 +The goal of this package is to provide a safe replacement for the node.js `Buffer`.
30 +
31 +It's a drop-in replacement for `Buffer`. You can use it by adding one `require` line to
32 +the top of your node.js modules:
33 +
34 +```js
35 +var Buffer = require('safe-buffer').Buffer
36 +
37 +// Existing buffer code will continue to work without issues:
38 +
39 +new Buffer('hey', 'utf8')
40 +new Buffer([1, 2, 3], 'utf8')
41 +new Buffer(obj)
42 +new Buffer(16) // create an uninitialized buffer (potentially unsafe)
43 +
44 +// But you can use these new explicit APIs to make clear what you want:
45 +
46 +Buffer.from('hey', 'utf8') // convert from many types to a Buffer
47 +Buffer.alloc(16) // create a zero-filled buffer (safe)
48 +Buffer.allocUnsafe(16) // create an uninitialized buffer (potentially unsafe)
49 +```
50 +
51 +## api
52 +
53 +### Class Method: Buffer.from(array)
54 +<!-- YAML
55 +added: v3.0.0
56 +-->
57 +
58 +* `array` {Array}
59 +
60 +Allocates a new `Buffer` using an `array` of octets.
61 +
62 +```js
63 +const buf = Buffer.from([0x62,0x75,0x66,0x66,0x65,0x72]);
64 + // creates a new Buffer containing ASCII bytes
65 + // ['b','u','f','f','e','r']
66 +```
67 +
68 +A `TypeError` will be thrown if `array` is not an `Array`.
69 +
70 +### Class Method: Buffer.from(arrayBuffer[, byteOffset[, length]])
71 +<!-- YAML
72 +added: v5.10.0
73 +-->
74 +
75 +* `arrayBuffer` {ArrayBuffer} The `.buffer` property of a `TypedArray` or
76 + a `new ArrayBuffer()`
77 +* `byteOffset` {Number} Default: `0`
78 +* `length` {Number} Default: `arrayBuffer.length - byteOffset`
79 +
80 +When passed a reference to the `.buffer` property of a `TypedArray` instance,
81 +the newly created `Buffer` will share the same allocated memory as the
82 +TypedArray.
83 +
84 +```js
85 +const arr = new Uint16Array(2);
86 +arr[0] = 5000;
87 +arr[1] = 4000;
88 +
89 +const buf = Buffer.from(arr.buffer); // shares the memory with arr;
90 +
91 +console.log(buf);
92 + // Prints: <Buffer 88 13 a0 0f>
93 +
94 +// changing the TypedArray changes the Buffer also
95 +arr[1] = 6000;
96 +
97 +console.log(buf);
98 + // Prints: <Buffer 88 13 70 17>
99 +```
100 +
101 +The optional `byteOffset` and `length` arguments specify a memory range within
102 +the `arrayBuffer` that will be shared by the `Buffer`.
103 +
104 +```js
105 +const ab = new ArrayBuffer(10);
106 +const buf = Buffer.from(ab, 0, 2);
107 +console.log(buf.length);
108 + // Prints: 2
109 +```
110 +
111 +A `TypeError` will be thrown if `arrayBuffer` is not an `ArrayBuffer`.
112 +
113 +### Class Method: Buffer.from(buffer)
114 +<!-- YAML
115 +added: v3.0.0
116 +-->
117 +
118 +* `buffer` {Buffer}
119 +
120 +Copies the passed `buffer` data onto a new `Buffer` instance.
121 +
122 +```js
123 +const buf1 = Buffer.from('buffer');
124 +const buf2 = Buffer.from(buf1);
125 +
126 +buf1[0] = 0x61;
127 +console.log(buf1.toString());
128 + // 'auffer'
129 +console.log(buf2.toString());
130 + // 'buffer' (copy is not changed)
131 +```
132 +
133 +A `TypeError` will be thrown if `buffer` is not a `Buffer`.
134 +
135 +### Class Method: Buffer.from(str[, encoding])
136 +<!-- YAML
137 +added: v5.10.0
138 +-->
139 +
140 +* `str` {String} String to encode.
141 +* `encoding` {String} Encoding to use, Default: `'utf8'`
142 +
143 +Creates a new `Buffer` containing the given JavaScript string `str`. If
144 +provided, the `encoding` parameter identifies the character encoding.
145 +If not provided, `encoding` defaults to `'utf8'`.
146 +
147 +```js
148 +const buf1 = Buffer.from('this is a tést');
149 +console.log(buf1.toString());
150 + // prints: this is a tést
151 +console.log(buf1.toString('ascii'));
152 + // prints: this is a tC)st
153 +
154 +const buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex');
155 +console.log(buf2.toString());
156 + // prints: this is a tést
157 +```
158 +
159 +A `TypeError` will be thrown if `str` is not a string.
160 +
161 +### Class Method: Buffer.alloc(size[, fill[, encoding]])
162 +<!-- YAML
163 +added: v5.10.0
164 +-->
165 +
166 +* `size` {Number}
167 +* `fill` {Value} Default: `undefined`
168 +* `encoding` {String} Default: `utf8`
169 +
170 +Allocates a new `Buffer` of `size` bytes. If `fill` is `undefined`, the
171 +`Buffer` will be *zero-filled*.
172 +
173 +```js
174 +const buf = Buffer.alloc(5);
175 +console.log(buf);
176 + // <Buffer 00 00 00 00 00>
177 +```
178 +
179 +The `size` must be less than or equal to the value of
180 +`require('buffer').kMaxLength` (on 64-bit architectures, `kMaxLength` is
181 +`(2^31)-1`). Otherwise, a [`RangeError`][] is thrown. A zero-length Buffer will
182 +be created if a `size` less than or equal to 0 is specified.
183 +
184 +If `fill` is specified, the allocated `Buffer` will be initialized by calling
185 +`buf.fill(fill)`. See [`buf.fill()`][] for more information.
186 +
187 +```js
188 +const buf = Buffer.alloc(5, 'a');
189 +console.log(buf);
190 + // <Buffer 61 61 61 61 61>
191 +```
192 +
193 +If both `fill` and `encoding` are specified, the allocated `Buffer` will be
194 +initialized by calling `buf.fill(fill, encoding)`. For example:
195 +
196 +```js
197 +const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64');
198 +console.log(buf);
199 + // <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64>
200 +```
201 +
202 +Calling `Buffer.alloc(size)` can be significantly slower than the alternative
203 +`Buffer.allocUnsafe(size)` but ensures that the newly created `Buffer` instance
204 +contents will *never contain sensitive data*.
205 +
206 +A `TypeError` will be thrown if `size` is not a number.
207 +
208 +### Class Method: Buffer.allocUnsafe(size)
209 +<!-- YAML
210 +added: v5.10.0
211 +-->
212 +
213 +* `size` {Number}
214 +
215 +Allocates a new *non-zero-filled* `Buffer` of `size` bytes. The `size` must
216 +be less than or equal to the value of `require('buffer').kMaxLength` (on 64-bit
217 +architectures, `kMaxLength` is `(2^31)-1`). Otherwise, a [`RangeError`][] is
218 +thrown. A zero-length Buffer will be created if a `size` less than or equal to
219 +0 is specified.
220 +
221 +The underlying memory for `Buffer` instances created in this way is *not
222 +initialized*. The contents of the newly created `Buffer` are unknown and
223 +*may contain sensitive data*. Use [`buf.fill(0)`][] to initialize such
224 +`Buffer` instances to zeroes.
225 +
226 +```js
227 +const buf = Buffer.allocUnsafe(5);
228 +console.log(buf);
229 + // <Buffer 78 e0 82 02 01>
230 + // (octets will be different, every time)
231 +buf.fill(0);
232 +console.log(buf);
233 + // <Buffer 00 00 00 00 00>
234 +```
235 +
236 +A `TypeError` will be thrown if `size` is not a number.
237 +
238 +Note that the `Buffer` module pre-allocates an internal `Buffer` instance of
239 +size `Buffer.poolSize` that is used as a pool for the fast allocation of new
240 +`Buffer` instances created using `Buffer.allocUnsafe(size)` (and the deprecated
241 +`new Buffer(size)` constructor) only when `size` is less than or equal to
242 +`Buffer.poolSize >> 1` (floor of `Buffer.poolSize` divided by two). The default
243 +value of `Buffer.poolSize` is `8192` but can be modified.
244 +
245 +Use of this pre-allocated internal memory pool is a key difference between
246 +calling `Buffer.alloc(size, fill)` vs. `Buffer.allocUnsafe(size).fill(fill)`.
247 +Specifically, `Buffer.alloc(size, fill)` will *never* use the internal Buffer
248 +pool, while `Buffer.allocUnsafe(size).fill(fill)` *will* use the internal
249 +Buffer pool if `size` is less than or equal to half `Buffer.poolSize`. The
250 +difference is subtle but can be important when an application requires the
251 +additional performance that `Buffer.allocUnsafe(size)` provides.
252 +
253 +### Class Method: Buffer.allocUnsafeSlow(size)
254 +<!-- YAML
255 +added: v5.10.0
256 +-->
257 +
258 +* `size` {Number}
259 +
260 +Allocates a new *non-zero-filled* and non-pooled `Buffer` of `size` bytes. The
261 +`size` must be less than or equal to the value of
262 +`require('buffer').kMaxLength` (on 64-bit architectures, `kMaxLength` is
263 +`(2^31)-1`). Otherwise, a [`RangeError`][] is thrown. A zero-length Buffer will
264 +be created if a `size` less than or equal to 0 is specified.
265 +
266 +The underlying memory for `Buffer` instances created in this way is *not
267 +initialized*. The contents of the newly created `Buffer` are unknown and
268 +*may contain sensitive data*. Use [`buf.fill(0)`][] to initialize such
269 +`Buffer` instances to zeroes.
270 +
271 +When using `Buffer.allocUnsafe()` to allocate new `Buffer` instances,
272 +allocations under 4KB are, by default, sliced from a single pre-allocated
273 +`Buffer`. This allows applications to avoid the garbage collection overhead of
274 +creating many individually allocated Buffers. This approach improves both
275 +performance and memory usage by eliminating the need to track and cleanup as
276 +many `Persistent` objects.
277 +
278 +However, in the case where a developer may need to retain a small chunk of
279 +memory from a pool for an indeterminate amount of time, it may be appropriate
280 +to create an un-pooled Buffer instance using `Buffer.allocUnsafeSlow()` then
281 +copy out the relevant bits.
282 +
283 +```js
284 +// need to keep around a few small chunks of memory
285 +const store = [];
286 +
287 +socket.on('readable', () => {
288 + const data = socket.read();
289 + // allocate for retained data
290 + const sb = Buffer.allocUnsafeSlow(10);
291 + // copy the data into the new allocation
292 + data.copy(sb, 0, 0, 10);
293 + store.push(sb);
294 +});
295 +```
296 +
297 +Use of `Buffer.allocUnsafeSlow()` should be used only as a last resort *after*
298 +a developer has observed undue memory retention in their applications.
299 +
300 +A `TypeError` will be thrown if `size` is not a number.
301 +
302 +### All the Rest
303 +
304 +The rest of the `Buffer` API is exactly the same as in node.js.
305 +[See the docs](https://nodejs.org/api/buffer.html).
306 +
307 +
308 +## Related links
309 +
310 +- [Node.js issue: Buffer(number) is unsafe](https://github.com/nodejs/node/issues/4660)
311 +- [Node.js Enhancement Proposal: Buffer.from/Buffer.alloc/Buffer.zalloc/Buffer() soft-deprecate](https://github.com/nodejs/node-eps/pull/4)
312 +
313 +## Why is `Buffer` unsafe?
314 +
315 +Today, the node.js `Buffer` constructor is overloaded to handle many different argument
316 +types like `String`, `Array`, `Object`, `TypedArrayView` (`Uint8Array`, etc.),
317 +`ArrayBuffer`, and also `Number`.
318 +
319 +The API is optimized for convenience: you can throw any type at it, and it will try to do
320 +what you want.
321 +
322 +Because the Buffer constructor is so powerful, you often see code like this:
323 +
324 +```js
325 +// Convert UTF-8 strings to hex
326 +function toHex (str) {
327 + return new Buffer(str).toString('hex')
328 +}
329 +```
330 +
331 +***But what happens if `toHex` is called with a `Number` argument?***
332 +
333 +### Remote Memory Disclosure
334 +
335 +If an attacker can make your program call the `Buffer` constructor with a `Number`
336 +argument, then they can make it allocate uninitialized memory from the node.js process.
337 +This could potentially disclose TLS private keys, user data, or database passwords.
338 +
339 +When the `Buffer` constructor is passed a `Number` argument, it returns an
340 +**UNINITIALIZED** block of memory of the specified `size`. When you create a `Buffer` like
341 +this, you **MUST** overwrite the contents before returning it to the user.
342 +
343 +From the [node.js docs](https://nodejs.org/api/buffer.html#buffer_new_buffer_size):
344 +
345 +> `new Buffer(size)`
346 +>
347 +> - `size` Number
348 +>
349 +> The underlying memory for `Buffer` instances created in this way is not initialized.
350 +> **The contents of a newly created `Buffer` are unknown and could contain sensitive
351 +> data.** Use `buf.fill(0)` to initialize a Buffer to zeroes.
352 +
353 +(Emphasis our own.)
354 +
355 +Whenever the programmer intended to create an uninitialized `Buffer` you often see code
356 +like this:
357 +
358 +```js
359 +var buf = new Buffer(16)
360 +
361 +// Immediately overwrite the uninitialized buffer with data from another buffer
362 +for (var i = 0; i < buf.length; i++) {
363 + buf[i] = otherBuf[i]
364 +}
365 +```
366 +
367 +
368 +### Would this ever be a problem in real code?
369 +
370 +Yes. It's surprisingly common to forget to check the type of your variables in a
371 +dynamically-typed language like JavaScript.
372 +
373 +Usually the consequences of assuming the wrong type is that your program crashes with an
374 +uncaught exception. But the failure mode for forgetting to check the type of arguments to
375 +the `Buffer` constructor is more catastrophic.
376 +
377 +Here's an example of a vulnerable service that takes a JSON payload and converts it to
378 +hex:
379 +
380 +```js
381 +// Take a JSON payload {str: "some string"} and convert it to hex
382 +var server = http.createServer(function (req, res) {
383 + var data = ''
384 + req.setEncoding('utf8')
385 + req.on('data', function (chunk) {
386 + data += chunk
387 + })
388 + req.on('end', function () {
389 + var body = JSON.parse(data)
390 + res.end(new Buffer(body.str).toString('hex'))
391 + })
392 +})
393 +
394 +server.listen(8080)
395 +```
396 +
397 +In this example, an http client just has to send:
398 +
399 +```json
400 +{
401 + "str": 1000
402 +}
403 +```
404 +
405 +and it will get back 1,000 bytes of uninitialized memory from the server.
406 +
407 +This is a very serious bug. It's similar in severity to the
408 +[the Heartbleed bug](http://heartbleed.com/) that allowed disclosure of OpenSSL process
409 +memory by remote attackers.
410 +
411 +
412 +### Which real-world packages were vulnerable?
413 +
414 +#### [`bittorrent-dht`](https://www.npmjs.com/package/bittorrent-dht)
415 +
416 +[Mathias Buus](https://github.com/mafintosh) and I
417 +([Feross Aboukhadijeh](http://feross.org/)) found this issue in one of our own packages,
418 +[`bittorrent-dht`](https://www.npmjs.com/package/bittorrent-dht). The bug would allow
419 +anyone on the internet to send a series of messages to a user of `bittorrent-dht` and get
420 +them to reveal 20 bytes at a time of uninitialized memory from the node.js process.
421 +
422 +Here's
423 +[the commit](https://github.com/feross/bittorrent-dht/commit/6c7da04025d5633699800a99ec3fbadf70ad35b8)
424 +that fixed it. We released a new fixed version, created a
425 +[Node Security Project disclosure](https://nodesecurity.io/advisories/68), and deprecated all
426 +vulnerable versions on npm so users will get a warning to upgrade to a newer version.
427 +
428 +#### [`ws`](https://www.npmjs.com/package/ws)
429 +
430 +That got us wondering if there were other vulnerable packages. Sure enough, within a short
431 +period of time, we found the same issue in [`ws`](https://www.npmjs.com/package/ws), the
432 +most popular WebSocket implementation in node.js.
433 +
434 +If certain APIs were called with `Number` parameters instead of `String` or `Buffer` as
435 +expected, then uninitialized server memory would be disclosed to the remote peer.
436 +
437 +These were the vulnerable methods:
438 +
439 +```js
440 +socket.send(number)
441 +socket.ping(number)
442 +socket.pong(number)
443 +```
444 +
445 +Here's a vulnerable socket server with some echo functionality:
446 +
447 +```js
448 +server.on('connection', function (socket) {
449 + socket.on('message', function (message) {
450 + message = JSON.parse(message)
451 + if (message.type === 'echo') {
452 + socket.send(message.data) // send back the user's message
453 + }
454 + })
455 +})
456 +```
457 +
458 +`socket.send(number)` called on the server, will disclose server memory.
459 +
460 +Here's [the release](https://github.com/websockets/ws/releases/tag/1.0.1) where the issue
461 +was fixed, with a more detailed explanation. Props to
462 +[Arnout Kazemier](https://github.com/3rd-Eden) for the quick fix. Here's the
463 +[Node Security Project disclosure](https://nodesecurity.io/advisories/67).
464 +
465 +
466 +### What's the solution?
467 +
468 +It's important that node.js offers a fast way to get memory otherwise performance-critical
469 +applications would needlessly get a lot slower.
470 +
471 +But we need a better way to *signal our intent* as programmers. **When we want
472 +uninitialized memory, we should request it explicitly.**
473 +
474 +Sensitive functionality should not be packed into a developer-friendly API that loosely
475 +accepts many different types. This type of API encourages the lazy practice of passing
476 +variables in without checking the type very carefully.
477 +
478 +#### A new API: `Buffer.allocUnsafe(number)`
479 +
480 +The functionality of creating buffers with uninitialized memory should be part of another
481 +API. We propose `Buffer.allocUnsafe(number)`. This way, it's not part of an API that
482 +frequently gets user input of all sorts of different types passed into it.
483 +
484 +```js
485 +var buf = Buffer.allocUnsafe(16) // careful, uninitialized memory!
486 +
487 +// Immediately overwrite the uninitialized buffer with data from another buffer
488 +for (var i = 0; i < buf.length; i++) {
489 + buf[i] = otherBuf[i]
490 +}
491 +```
492 +
493 +
494 +### How do we fix node.js core?
495 +
496 +We sent [a PR to node.js core](https://github.com/nodejs/node/pull/4514) (merged as
497 +`semver-major`) which defends against one case:
498 +
499 +```js
500 +var str = 16
501 +new Buffer(str, 'utf8')
502 +```
503 +
504 +In this situation, it's implied that the programmer intended the first argument to be a
505 +string, since they passed an encoding as a second argument. Today, node.js will allocate
506 +uninitialized memory in the case of `new Buffer(number, encoding)`, which is probably not
507 +what the programmer intended.
508 +
509 +But this is only a partial solution, since if the programmer does `new Buffer(variable)`
510 +(without an `encoding` parameter) there's no way to know what they intended. If `variable`
511 +is sometimes a number, then uninitialized memory will sometimes be returned.
512 +
513 +### What's the real long-term fix?
514 +
515 +We could deprecate and remove `new Buffer(number)` and use `Buffer.allocUnsafe(number)` when
516 +we need uninitialized memory. But that would break 1000s of packages.
517 +
518 +~~We believe the best solution is to:~~
519 +
520 +~~1. Change `new Buffer(number)` to return safe, zeroed-out memory~~
521 +
522 +~~2. Create a new API for creating uninitialized Buffers. We propose: `Buffer.allocUnsafe(number)`~~
523 +
524 +#### Update
525 +
526 +We now support adding three new APIs:
527 +
528 +- `Buffer.from(value)` - convert from any type to a buffer
529 +- `Buffer.alloc(size)` - create a zero-filled buffer
530 +- `Buffer.allocUnsafe(size)` - create an uninitialized buffer with given size
531 +
532 +This solves the core problem that affected `ws` and `bittorrent-dht` which is
533 +`Buffer(variable)` getting tricked into taking a number argument.
534 +
535 +This way, existing code continues working and the impact on the npm ecosystem will be
536 +minimal. Over time, npm maintainers can migrate performance-critical code to use
537 +`Buffer.allocUnsafe(number)` instead of `new Buffer(number)`.
538 +
539 +
540 +### Conclusion
541 +
542 +We think there's a serious design issue with the `Buffer` API as it exists today. It
543 +promotes insecure software by putting high-risk functionality into a convenient API
544 +with friendly "developer ergonomics".
545 +
546 +This wasn't merely a theoretical exercise because we found the issue in some of the
547 +most popular npm packages.
548 +
549 +Fortunately, there's an easy fix that can be applied today. Use `safe-buffer` in place of
550 +`buffer`.
551 +
552 +```js
553 +var Buffer = require('safe-buffer').Buffer
554 +```
555 +
556 +Eventually, we hope that node.js core can switch to this new, safer behavior. We believe
557 +the impact on the ecosystem would be minimal since it's not a breaking change.
558 +Well-maintained, popular packages would be updated to use `Buffer.alloc` quickly, while
559 +older, insecure packages would magically become safe from this attack vector.
560 +
561 +
562 +## links
563 +
564 +- [Node.js PR: buffer: throw if both length and enc are passed](https://github.com/nodejs/node/pull/4514)
565 +- [Node Security Project disclosure for `ws`](https://nodesecurity.io/advisories/67)
566 +- [Node Security Project disclosure for`bittorrent-dht`](https://nodesecurity.io/advisories/68)
567 +
568 +
569 +## credit
570 +
571 +The original issues in `bittorrent-dht`
572 +([disclosure](https://nodesecurity.io/advisories/68)) and
573 +`ws` ([disclosure](https://nodesecurity.io/advisories/67)) were discovered by
574 +[Mathias Buus](https://github.com/mafintosh) and
575 +[Feross Aboukhadijeh](http://feross.org/).
576 +
577 +Thanks to [Adam Baldwin](https://github.com/evilpacket) for helping disclose these issues
578 +and for his work running the [Node Security Project](https://nodesecurity.io/).
579 +
580 +Thanks to [John Hiesey](https://github.com/jhiesey) for proofreading this README and
581 +auditing the code.
582 +
583 +
584 +## license
585 +
586 +MIT. Copyright (C) [Feross Aboukhadijeh](http://feross.org)
1 +declare module "safe-buffer" {
2 + export class Buffer {
3 + length: number
4 + write(string: string, offset?: number, length?: number, encoding?: string): number;
5 + toString(encoding?: string, start?: number, end?: number): string;
6 + toJSON(): { type: 'Buffer', data: any[] };
7 + equals(otherBuffer: Buffer): boolean;
8 + compare(otherBuffer: Buffer, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number;
9 + copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number;
10 + slice(start?: number, end?: number): Buffer;
11 + writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
12 + writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
13 + writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
14 + writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
15 + readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number;
16 + readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number;
17 + readIntLE(offset: number, byteLength: number, noAssert?: boolean): number;
18 + readIntBE(offset: number, byteLength: number, noAssert?: boolean): number;
19 + readUInt8(offset: number, noAssert?: boolean): number;
20 + readUInt16LE(offset: number, noAssert?: boolean): number;
21 + readUInt16BE(offset: number, noAssert?: boolean): number;
22 + readUInt32LE(offset: number, noAssert?: boolean): number;
23 + readUInt32BE(offset: number, noAssert?: boolean): number;
24 + readInt8(offset: number, noAssert?: boolean): number;
25 + readInt16LE(offset: number, noAssert?: boolean): number;
26 + readInt16BE(offset: number, noAssert?: boolean): number;
27 + readInt32LE(offset: number, noAssert?: boolean): number;
28 + readInt32BE(offset: number, noAssert?: boolean): number;
29 + readFloatLE(offset: number, noAssert?: boolean): number;
30 + readFloatBE(offset: number, noAssert?: boolean): number;
31 + readDoubleLE(offset: number, noAssert?: boolean): number;
32 + readDoubleBE(offset: number, noAssert?: boolean): number;
33 + swap16(): Buffer;
34 + swap32(): Buffer;
35 + swap64(): Buffer;
36 + writeUInt8(value: number, offset: number, noAssert?: boolean): number;
37 + writeUInt16LE(value: number, offset: number, noAssert?: boolean): number;
38 + writeUInt16BE(value: number, offset: number, noAssert?: boolean): number;
39 + writeUInt32LE(value: number, offset: number, noAssert?: boolean): number;
40 + writeUInt32BE(value: number, offset: number, noAssert?: boolean): number;
41 + writeInt8(value: number, offset: number, noAssert?: boolean): number;
42 + writeInt16LE(value: number, offset: number, noAssert?: boolean): number;
43 + writeInt16BE(value: number, offset: number, noAssert?: boolean): number;
44 + writeInt32LE(value: number, offset: number, noAssert?: boolean): number;
45 + writeInt32BE(value: number, offset: number, noAssert?: boolean): number;
46 + writeFloatLE(value: number, offset: number, noAssert?: boolean): number;
47 + writeFloatBE(value: number, offset: number, noAssert?: boolean): number;
48 + writeDoubleLE(value: number, offset: number, noAssert?: boolean): number;
49 + writeDoubleBE(value: number, offset: number, noAssert?: boolean): number;
50 + fill(value: any, offset?: number, end?: number): this;
51 + indexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number;
52 + lastIndexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number;
53 + includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean;
54 +
55 + /**
56 + * Allocates a new buffer containing the given {str}.
57 + *
58 + * @param str String to store in buffer.
59 + * @param encoding encoding to use, optional. Default is 'utf8'
60 + */
61 + constructor (str: string, encoding?: string);
62 + /**
63 + * Allocates a new buffer of {size} octets.
64 + *
65 + * @param size count of octets to allocate.
66 + */
67 + constructor (size: number);
68 + /**
69 + * Allocates a new buffer containing the given {array} of octets.
70 + *
71 + * @param array The octets to store.
72 + */
73 + constructor (array: Uint8Array);
74 + /**
75 + * Produces a Buffer backed by the same allocated memory as
76 + * the given {ArrayBuffer}.
77 + *
78 + *
79 + * @param arrayBuffer The ArrayBuffer with which to share memory.
80 + */
81 + constructor (arrayBuffer: ArrayBuffer);
82 + /**
83 + * Allocates a new buffer containing the given {array} of octets.
84 + *
85 + * @param array The octets to store.
86 + */
87 + constructor (array: any[]);
88 + /**
89 + * Copies the passed {buffer} data onto a new {Buffer} instance.
90 + *
91 + * @param buffer The buffer to copy.
92 + */
93 + constructor (buffer: Buffer);
94 + prototype: Buffer;
95 + /**
96 + * Allocates a new Buffer using an {array} of octets.
97 + *
98 + * @param array
99 + */
100 + static from(array: any[]): Buffer;
101 + /**
102 + * When passed a reference to the .buffer property of a TypedArray instance,
103 + * the newly created Buffer will share the same allocated memory as the TypedArray.
104 + * The optional {byteOffset} and {length} arguments specify a memory range
105 + * within the {arrayBuffer} that will be shared by the Buffer.
106 + *
107 + * @param arrayBuffer The .buffer property of a TypedArray or a new ArrayBuffer()
108 + * @param byteOffset
109 + * @param length
110 + */
111 + static from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer;
112 + /**
113 + * Copies the passed {buffer} data onto a new Buffer instance.
114 + *
115 + * @param buffer
116 + */
117 + static from(buffer: Buffer): Buffer;
118 + /**
119 + * Creates a new Buffer containing the given JavaScript string {str}.
120 + * If provided, the {encoding} parameter identifies the character encoding.
121 + * If not provided, {encoding} defaults to 'utf8'.
122 + *
123 + * @param str
124 + */
125 + static from(str: string, encoding?: string): Buffer;
126 + /**
127 + * Returns true if {obj} is a Buffer
128 + *
129 + * @param obj object to test.
130 + */
131 + static isBuffer(obj: any): obj is Buffer;
132 + /**
133 + * Returns true if {encoding} is a valid encoding argument.
134 + * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex'
135 + *
136 + * @param encoding string to test.
137 + */
138 + static isEncoding(encoding: string): boolean;
139 + /**
140 + * Gives the actual byte length of a string. encoding defaults to 'utf8'.
141 + * This is not the same as String.prototype.length since that returns the number of characters in a string.
142 + *
143 + * @param string string to test.
144 + * @param encoding encoding used to evaluate (defaults to 'utf8')
145 + */
146 + static byteLength(string: string, encoding?: string): number;
147 + /**
148 + * Returns a buffer which is the result of concatenating all the buffers in the list together.
149 + *
150 + * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer.
151 + * If the list has exactly one item, then the first item of the list is returned.
152 + * If the list has more than one item, then a new Buffer is created.
153 + *
154 + * @param list An array of Buffer objects to concatenate
155 + * @param totalLength Total length of the buffers when concatenated.
156 + * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly.
157 + */
158 + static concat(list: Buffer[], totalLength?: number): Buffer;
159 + /**
160 + * The same as buf1.compare(buf2).
161 + */
162 + static compare(buf1: Buffer, buf2: Buffer): number;
163 + /**
164 + * Allocates a new buffer of {size} octets.
165 + *
166 + * @param size count of octets to allocate.
167 + * @param fill if specified, buffer will be initialized by calling buf.fill(fill).
168 + * If parameter is omitted, buffer will be filled with zeros.
169 + * @param encoding encoding used for call to buf.fill while initalizing
170 + */
171 + static alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer;
172 + /**
173 + * Allocates a new buffer of {size} octets, leaving memory not initialized, so the contents
174 + * of the newly created Buffer are unknown and may contain sensitive data.
175 + *
176 + * @param size count of octets to allocate
177 + */
178 + static allocUnsafe(size: number): Buffer;
179 + /**
180 + * Allocates a new non-pooled buffer of {size} octets, leaving memory not initialized, so the contents
181 + * of the newly created Buffer are unknown and may contain sensitive data.
182 + *
183 + * @param size count of octets to allocate
184 + */
185 + static allocUnsafeSlow(size: number): Buffer;
186 + }
187 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/* eslint-disable node/no-deprecated-api */
2 +var buffer = require('buffer')
3 +var Buffer = buffer.Buffer
4 +
5 +// alternative to using Object.keys for old browsers
6 +function copyProps (src, dst) {
7 + for (var key in src) {
8 + dst[key] = src[key]
9 + }
10 +}
11 +if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
12 + module.exports = buffer
13 +} else {
14 + // Copy properties from require('buffer')
15 + copyProps(buffer, exports)
16 + exports.Buffer = SafeBuffer
17 +}
18 +
19 +function SafeBuffer (arg, encodingOrOffset, length) {
20 + return Buffer(arg, encodingOrOffset, length)
21 +}
22 +
23 +SafeBuffer.prototype = Object.create(Buffer.prototype)
24 +
25 +// Copy static methods from Buffer
26 +copyProps(Buffer, SafeBuffer)
27 +
28 +SafeBuffer.from = function (arg, encodingOrOffset, length) {
29 + if (typeof arg === 'number') {
30 + throw new TypeError('Argument must not be a number')
31 + }
32 + return Buffer(arg, encodingOrOffset, length)
33 +}
34 +
35 +SafeBuffer.alloc = function (size, fill, encoding) {
36 + if (typeof size !== 'number') {
37 + throw new TypeError('Argument must be a number')
38 + }
39 + var buf = Buffer(size)
40 + if (fill !== undefined) {
41 + if (typeof encoding === 'string') {
42 + buf.fill(fill, encoding)
43 + } else {
44 + buf.fill(fill)
45 + }
46 + } else {
47 + buf.fill(0)
48 + }
49 + return buf
50 +}
51 +
52 +SafeBuffer.allocUnsafe = function (size) {
53 + if (typeof size !== 'number') {
54 + throw new TypeError('Argument must be a number')
55 + }
56 + return Buffer(size)
57 +}
58 +
59 +SafeBuffer.allocUnsafeSlow = function (size) {
60 + if (typeof size !== 'number') {
61 + throw new TypeError('Argument must be a number')
62 + }
63 + return buffer.SlowBuffer(size)
64 +}
1 +{
2 + "_from": "safe-buffer@5.2.0",
3 + "_id": "safe-buffer@5.2.0",
4 + "_inBundle": false,
5 + "_integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
6 + "_location": "/express-session/safe-buffer",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "version",
10 + "registry": true,
11 + "raw": "safe-buffer@5.2.0",
12 + "name": "safe-buffer",
13 + "escapedName": "safe-buffer",
14 + "rawSpec": "5.2.0",
15 + "saveSpec": null,
16 + "fetchSpec": "5.2.0"
17 + },
18 + "_requiredBy": [
19 + "/express-session"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
22 + "_shasum": "b74daec49b1148f88c64b68d49b1e815c1f2f519",
23 + "_spec": "safe-buffer@5.2.0",
24 + "_where": "C:\\Users\\fheld\\Desktop\\khuhub\\mapmory\\Mapmory\\node_modules\\express-session",
25 + "author": {
26 + "name": "Feross Aboukhadijeh",
27 + "email": "feross@feross.org",
28 + "url": "http://feross.org"
29 + },
30 + "bugs": {
31 + "url": "https://github.com/feross/safe-buffer/issues"
32 + },
33 + "bundleDependencies": false,
34 + "deprecated": false,
35 + "description": "Safer Node.js Buffer API",
36 + "devDependencies": {
37 + "standard": "*",
38 + "tape": "^4.0.0"
39 + },
40 + "homepage": "https://github.com/feross/safe-buffer",
41 + "keywords": [
42 + "buffer",
43 + "buffer allocate",
44 + "node security",
45 + "safe",
46 + "safe-buffer",
47 + "security",
48 + "uninitialized"
49 + ],
50 + "license": "MIT",
51 + "main": "index.js",
52 + "name": "safe-buffer",
53 + "repository": {
54 + "type": "git",
55 + "url": "git://github.com/feross/safe-buffer.git"
56 + },
57 + "scripts": {
58 + "test": "standard && tape test/*.js"
59 + },
60 + "types": "index.d.ts",
61 + "version": "5.2.0"
62 +}
1 +{
2 + "_from": "express-session",
3 + "_id": "express-session@1.17.1",
4 + "_inBundle": false,
5 + "_integrity": "sha512-UbHwgqjxQZJiWRTMyhvWGvjBQduGCSBDhhZXYenziMFjxst5rMV+aJZ6hKPHZnPyHGsrqRICxtX8jtEbm/z36Q==",
6 + "_location": "/express-session",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "tag",
10 + "registry": true,
11 + "raw": "express-session",
12 + "name": "express-session",
13 + "escapedName": "express-session",
14 + "rawSpec": "",
15 + "saveSpec": null,
16 + "fetchSpec": "latest"
17 + },
18 + "_requiredBy": [
19 + "#USER",
20 + "/"
21 + ],
22 + "_resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz",
23 + "_shasum": "36ecbc7034566d38c8509885c044d461c11bf357",
24 + "_spec": "express-session",
25 + "_where": "C:\\Users\\fheld\\Desktop\\khuhub\\mapmory\\Mapmory",
26 + "author": {
27 + "name": "TJ Holowaychuk",
28 + "email": "tj@vision-media.ca",
29 + "url": "http://tjholowaychuk.com"
30 + },
31 + "bugs": {
32 + "url": "https://github.com/expressjs/session/issues"
33 + },
34 + "bundleDependencies": false,
35 + "contributors": [
36 + {
37 + "name": "Douglas Christopher Wilson",
38 + "email": "doug@somethingdoug.com"
39 + },
40 + {
41 + "name": "Joe Wagner",
42 + "email": "njwjs722@gmail.com"
43 + }
44 + ],
45 + "dependencies": {
46 + "cookie": "0.4.0",
47 + "cookie-signature": "1.0.6",
48 + "debug": "2.6.9",
49 + "depd": "~2.0.0",
50 + "on-headers": "~1.0.2",
51 + "parseurl": "~1.3.3",
52 + "safe-buffer": "5.2.0",
53 + "uid-safe": "~2.1.5"
54 + },
55 + "deprecated": false,
56 + "description": "Simple session middleware for Express",
57 + "devDependencies": {
58 + "after": "0.8.2",
59 + "cookie-parser": "1.4.5",
60 + "eslint": "3.19.0",
61 + "eslint-plugin-markdown": "1.0.2",
62 + "express": "4.17.1",
63 + "mocha": "7.1.1",
64 + "nyc": "15.0.1",
65 + "supertest": "4.0.2"
66 + },
67 + "engines": {
68 + "node": ">= 0.8.0"
69 + },
70 + "files": [
71 + "session/",
72 + "HISTORY.md",
73 + "LICENSE",
74 + "index.js"
75 + ],
76 + "homepage": "https://github.com/expressjs/session#readme",
77 + "license": "MIT",
78 + "name": "express-session",
79 + "repository": {
80 + "type": "git",
81 + "url": "git+https://github.com/expressjs/session.git"
82 + },
83 + "scripts": {
84 + "lint": "eslint --plugin markdown --ext js,md . && node ./scripts/lint-readme.js",
85 + "test": "mocha --require test/support/env --check-leaks --bail --no-exit --reporter spec test/",
86 + "test-cov": "nyc npm test",
87 + "test-travis": "nyc npm test -- --no-exit",
88 + "version": "node scripts/version-history.js && git add HISTORY.md"
89 + },
90 + "version": "1.17.1"
91 +}
1 +/*!
2 + * Connect - session - Cookie
3 + * Copyright(c) 2010 Sencha Inc.
4 + * Copyright(c) 2011 TJ Holowaychuk
5 + * MIT Licensed
6 + */
7 +
8 +'use strict';
9 +
10 +/**
11 + * Module dependencies.
12 + */
13 +
14 +var cookie = require('cookie')
15 +var deprecate = require('depd')('express-session')
16 +
17 +/**
18 + * Initialize a new `Cookie` with the given `options`.
19 + *
20 + * @param {IncomingMessage} req
21 + * @param {Object} options
22 + * @api private
23 + */
24 +
25 +var Cookie = module.exports = function Cookie(options) {
26 + this.path = '/';
27 + this.maxAge = null;
28 + this.httpOnly = true;
29 +
30 + if (options) {
31 + if (typeof options !== 'object') {
32 + throw new TypeError('argument options must be a object')
33 + }
34 +
35 + for (var key in options) {
36 + if (key !== 'data') {
37 + this[key] = options[key]
38 + }
39 + }
40 + }
41 +
42 + if (this.originalMaxAge === undefined || this.originalMaxAge === null) {
43 + this.originalMaxAge = this.maxAge
44 + }
45 +};
46 +
47 +/*!
48 + * Prototype.
49 + */
50 +
51 +Cookie.prototype = {
52 +
53 + /**
54 + * Set expires `date`.
55 + *
56 + * @param {Date} date
57 + * @api public
58 + */
59 +
60 + set expires(date) {
61 + this._expires = date;
62 + this.originalMaxAge = this.maxAge;
63 + },
64 +
65 + /**
66 + * Get expires `date`.
67 + *
68 + * @return {Date}
69 + * @api public
70 + */
71 +
72 + get expires() {
73 + return this._expires;
74 + },
75 +
76 + /**
77 + * Set expires via max-age in `ms`.
78 + *
79 + * @param {Number} ms
80 + * @api public
81 + */
82 +
83 + set maxAge(ms) {
84 + if (ms && typeof ms !== 'number' && !(ms instanceof Date)) {
85 + throw new TypeError('maxAge must be a number or Date')
86 + }
87 +
88 + if (ms instanceof Date) {
89 + deprecate('maxAge as Date; pass number of milliseconds instead')
90 + }
91 +
92 + this.expires = typeof ms === 'number'
93 + ? new Date(Date.now() + ms)
94 + : ms;
95 + },
96 +
97 + /**
98 + * Get expires max-age in `ms`.
99 + *
100 + * @return {Number}
101 + * @api public
102 + */
103 +
104 + get maxAge() {
105 + return this.expires instanceof Date
106 + ? this.expires.valueOf() - Date.now()
107 + : this.expires;
108 + },
109 +
110 + /**
111 + * Return cookie data object.
112 + *
113 + * @return {Object}
114 + * @api private
115 + */
116 +
117 + get data() {
118 + return {
119 + originalMaxAge: this.originalMaxAge
120 + , expires: this._expires
121 + , secure: this.secure
122 + , httpOnly: this.httpOnly
123 + , domain: this.domain
124 + , path: this.path
125 + , sameSite: this.sameSite
126 + }
127 + },
128 +
129 + /**
130 + * Return a serialized cookie string.
131 + *
132 + * @return {String}
133 + * @api public
134 + */
135 +
136 + serialize: function(name, val){
137 + return cookie.serialize(name, val, this.data);
138 + },
139 +
140 + /**
141 + * Return JSON representation of this cookie.
142 + *
143 + * @return {Object}
144 + * @api private
145 + */
146 +
147 + toJSON: function(){
148 + return this.data;
149 + }
150 +};
1 +/*!
2 + * express-session
3 + * Copyright(c) 2010 Sencha Inc.
4 + * Copyright(c) 2011 TJ Holowaychuk
5 + * Copyright(c) 2015 Douglas Christopher Wilson
6 + * MIT Licensed
7 + */
8 +
9 +'use strict';
10 +
11 +/**
12 + * Module dependencies.
13 + * @private
14 + */
15 +
16 +var Store = require('./store')
17 +var util = require('util')
18 +
19 +/**
20 + * Shim setImmediate for node.js < 0.10
21 + * @private
22 + */
23 +
24 +/* istanbul ignore next */
25 +var defer = typeof setImmediate === 'function'
26 + ? setImmediate
27 + : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) }
28 +
29 +/**
30 + * Module exports.
31 + */
32 +
33 +module.exports = MemoryStore
34 +
35 +/**
36 + * A session store in memory.
37 + * @public
38 + */
39 +
40 +function MemoryStore() {
41 + Store.call(this)
42 + this.sessions = Object.create(null)
43 +}
44 +
45 +/**
46 + * Inherit from Store.
47 + */
48 +
49 +util.inherits(MemoryStore, Store)
50 +
51 +/**
52 + * Get all active sessions.
53 + *
54 + * @param {function} callback
55 + * @public
56 + */
57 +
58 +MemoryStore.prototype.all = function all(callback) {
59 + var sessionIds = Object.keys(this.sessions)
60 + var sessions = Object.create(null)
61 +
62 + for (var i = 0; i < sessionIds.length; i++) {
63 + var sessionId = sessionIds[i]
64 + var session = getSession.call(this, sessionId)
65 +
66 + if (session) {
67 + sessions[sessionId] = session;
68 + }
69 + }
70 +
71 + callback && defer(callback, null, sessions)
72 +}
73 +
74 +/**
75 + * Clear all sessions.
76 + *
77 + * @param {function} callback
78 + * @public
79 + */
80 +
81 +MemoryStore.prototype.clear = function clear(callback) {
82 + this.sessions = Object.create(null)
83 + callback && defer(callback)
84 +}
85 +
86 +/**
87 + * Destroy the session associated with the given session ID.
88 + *
89 + * @param {string} sessionId
90 + * @public
91 + */
92 +
93 +MemoryStore.prototype.destroy = function destroy(sessionId, callback) {
94 + delete this.sessions[sessionId]
95 + callback && defer(callback)
96 +}
97 +
98 +/**
99 + * Fetch session by the given session ID.
100 + *
101 + * @param {string} sessionId
102 + * @param {function} callback
103 + * @public
104 + */
105 +
106 +MemoryStore.prototype.get = function get(sessionId, callback) {
107 + defer(callback, null, getSession.call(this, sessionId))
108 +}
109 +
110 +/**
111 + * Commit the given session associated with the given sessionId to the store.
112 + *
113 + * @param {string} sessionId
114 + * @param {object} session
115 + * @param {function} callback
116 + * @public
117 + */
118 +
119 +MemoryStore.prototype.set = function set(sessionId, session, callback) {
120 + this.sessions[sessionId] = JSON.stringify(session)
121 + callback && defer(callback)
122 +}
123 +
124 +/**
125 + * Get number of active sessions.
126 + *
127 + * @param {function} callback
128 + * @public
129 + */
130 +
131 +MemoryStore.prototype.length = function length(callback) {
132 + this.all(function (err, sessions) {
133 + if (err) return callback(err)
134 + callback(null, Object.keys(sessions).length)
135 + })
136 +}
137 +
138 +/**
139 + * Touch the given session object associated with the given session ID.
140 + *
141 + * @param {string} sessionId
142 + * @param {object} session
143 + * @param {function} callback
144 + * @public
145 + */
146 +
147 +MemoryStore.prototype.touch = function touch(sessionId, session, callback) {
148 + var currentSession = getSession.call(this, sessionId)
149 +
150 + if (currentSession) {
151 + // update expiration
152 + currentSession.cookie = session.cookie
153 + this.sessions[sessionId] = JSON.stringify(currentSession)
154 + }
155 +
156 + callback && defer(callback)
157 +}
158 +
159 +/**
160 + * Get session from the store.
161 + * @private
162 + */
163 +
164 +function getSession(sessionId) {
165 + var sess = this.sessions[sessionId]
166 +
167 + if (!sess) {
168 + return
169 + }
170 +
171 + // parse
172 + sess = JSON.parse(sess)
173 +
174 + if (sess.cookie) {
175 + var expires = typeof sess.cookie.expires === 'string'
176 + ? new Date(sess.cookie.expires)
177 + : sess.cookie.expires
178 +
179 + // destroy expired session
180 + if (expires && expires <= Date.now()) {
181 + delete this.sessions[sessionId]
182 + return
183 + }
184 + }
185 +
186 + return sess
187 +}
1 +/*!
2 + * Connect - session - Session
3 + * Copyright(c) 2010 Sencha Inc.
4 + * Copyright(c) 2011 TJ Holowaychuk
5 + * MIT Licensed
6 + */
7 +
8 +'use strict';
9 +
10 +/**
11 + * Expose Session.
12 + */
13 +
14 +module.exports = Session;
15 +
16 +/**
17 + * Create a new `Session` with the given request and `data`.
18 + *
19 + * @param {IncomingRequest} req
20 + * @param {Object} data
21 + * @api private
22 + */
23 +
24 +function Session(req, data) {
25 + Object.defineProperty(this, 'req', { value: req });
26 + Object.defineProperty(this, 'id', { value: req.sessionID });
27 +
28 + if (typeof data === 'object' && data !== null) {
29 + // merge data into this, ignoring prototype properties
30 + for (var prop in data) {
31 + if (!(prop in this)) {
32 + this[prop] = data[prop]
33 + }
34 + }
35 + }
36 +}
37 +
38 +/**
39 + * Update reset `.cookie.maxAge` to prevent
40 + * the cookie from expiring when the
41 + * session is still active.
42 + *
43 + * @return {Session} for chaining
44 + * @api public
45 + */
46 +
47 +defineMethod(Session.prototype, 'touch', function touch() {
48 + return this.resetMaxAge();
49 +});
50 +
51 +/**
52 + * Reset `.maxAge` to `.originalMaxAge`.
53 + *
54 + * @return {Session} for chaining
55 + * @api public
56 + */
57 +
58 +defineMethod(Session.prototype, 'resetMaxAge', function resetMaxAge() {
59 + this.cookie.maxAge = this.cookie.originalMaxAge;
60 + return this;
61 +});
62 +
63 +/**
64 + * Save the session data with optional callback `fn(err)`.
65 + *
66 + * @param {Function} fn
67 + * @return {Session} for chaining
68 + * @api public
69 + */
70 +
71 +defineMethod(Session.prototype, 'save', function save(fn) {
72 + this.req.sessionStore.set(this.id, this, fn || function(){});
73 + return this;
74 +});
75 +
76 +/**
77 + * Re-loads the session data _without_ altering
78 + * the maxAge properties. Invokes the callback `fn(err)`,
79 + * after which time if no exception has occurred the
80 + * `req.session` property will be a new `Session` object,
81 + * although representing the same session.
82 + *
83 + * @param {Function} fn
84 + * @return {Session} for chaining
85 + * @api public
86 + */
87 +
88 +defineMethod(Session.prototype, 'reload', function reload(fn) {
89 + var req = this.req
90 + var store = this.req.sessionStore
91 +
92 + store.get(this.id, function(err, sess){
93 + if (err) return fn(err);
94 + if (!sess) return fn(new Error('failed to load session'));
95 + store.createSession(req, sess);
96 + fn();
97 + });
98 + return this;
99 +});
100 +
101 +/**
102 + * Destroy `this` session.
103 + *
104 + * @param {Function} fn
105 + * @return {Session} for chaining
106 + * @api public
107 + */
108 +
109 +defineMethod(Session.prototype, 'destroy', function destroy(fn) {
110 + delete this.req.session;
111 + this.req.sessionStore.destroy(this.id, fn);
112 + return this;
113 +});
114 +
115 +/**
116 + * Regenerate this request's session.
117 + *
118 + * @param {Function} fn
119 + * @return {Session} for chaining
120 + * @api public
121 + */
122 +
123 +defineMethod(Session.prototype, 'regenerate', function regenerate(fn) {
124 + this.req.sessionStore.regenerate(this.req, fn);
125 + return this;
126 +});
127 +
128 +/**
129 + * Helper function for creating a method on a prototype.
130 + *
131 + * @param {Object} obj
132 + * @param {String} name
133 + * @param {Function} fn
134 + * @private
135 + */
136 +function defineMethod(obj, name, fn) {
137 + Object.defineProperty(obj, name, {
138 + configurable: true,
139 + enumerable: false,
140 + value: fn,
141 + writable: true
142 + });
143 +};
1 +/*!
2 + * Connect - session - Store
3 + * Copyright(c) 2010 Sencha Inc.
4 + * Copyright(c) 2011 TJ Holowaychuk
5 + * MIT Licensed
6 + */
7 +
8 +'use strict';
9 +
10 +/**
11 + * Module dependencies.
12 + * @private
13 + */
14 +
15 +var Cookie = require('./cookie')
16 +var EventEmitter = require('events').EventEmitter
17 +var Session = require('./session')
18 +var util = require('util')
19 +
20 +/**
21 + * Module exports.
22 + * @public
23 + */
24 +
25 +module.exports = Store
26 +
27 +/**
28 + * Abstract base class for session stores.
29 + * @public
30 + */
31 +
32 +function Store () {
33 + EventEmitter.call(this)
34 +}
35 +
36 +/**
37 + * Inherit from EventEmitter.
38 + */
39 +
40 +util.inherits(Store, EventEmitter)
41 +
42 +/**
43 + * Re-generate the given requests's session.
44 + *
45 + * @param {IncomingRequest} req
46 + * @return {Function} fn
47 + * @api public
48 + */
49 +
50 +Store.prototype.regenerate = function(req, fn){
51 + var self = this;
52 + this.destroy(req.sessionID, function(err){
53 + self.generate(req);
54 + fn(err);
55 + });
56 +};
57 +
58 +/**
59 + * Load a `Session` instance via the given `sid`
60 + * and invoke the callback `fn(err, sess)`.
61 + *
62 + * @param {String} sid
63 + * @param {Function} fn
64 + * @api public
65 + */
66 +
67 +Store.prototype.load = function(sid, fn){
68 + var self = this;
69 + this.get(sid, function(err, sess){
70 + if (err) return fn(err);
71 + if (!sess) return fn();
72 + var req = { sessionID: sid, sessionStore: self };
73 + fn(null, self.createSession(req, sess))
74 + });
75 +};
76 +
77 +/**
78 + * Create session from JSON `sess` data.
79 + *
80 + * @param {IncomingRequest} req
81 + * @param {Object} sess
82 + * @return {Session}
83 + * @api private
84 + */
85 +
86 +Store.prototype.createSession = function(req, sess){
87 + var expires = sess.cookie.expires
88 + var originalMaxAge = sess.cookie.originalMaxAge
89 +
90 + sess.cookie = new Cookie(sess.cookie);
91 +
92 + if (typeof expires === 'string') {
93 + // convert expires to a Date object
94 + sess.cookie.expires = new Date(expires)
95 + }
96 +
97 + // keep originalMaxAge intact
98 + sess.cookie.originalMaxAge = originalMaxAge
99 +
100 + req.session = new Session(req, sess);
101 + return req.session;
102 +};
1 +1.0.2 / 2019-02-21
2 +==================
3 +
4 + * Fix `res.writeHead` patch missing return value
5 +
6 +1.0.1 / 2015-09-29
7 +==================
8 +
9 + * perf: enable strict mode
10 +
11 +1.0.0 / 2014-08-10
12 +==================
13 +
14 + * Honor `res.statusCode` change in `listener`
15 + * Move to `jshttp` organization
16 + * Prevent `arguments`-related de-opt
17 +
18 +0.0.0 / 2014-05-13
19 +==================
20 +
21 + * Initial implementation
1 +(The MIT License)
2 +
3 +Copyright (c) 2014 Douglas Christopher Wilson
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining
6 +a copy of this software and associated documentation files (the
7 +'Software'), to deal in the Software without restriction, including
8 +without limitation the rights to use, copy, modify, merge, publish,
9 +distribute, sublicense, and/or sell copies of the Software, and to
10 +permit persons to whom the Software is furnished to do so, subject to
11 +the following conditions:
12 +
13 +The above copyright notice and this permission notice shall be
14 +included in all copies or substantial portions of the Software.
15 +
16 +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 +# on-headers
2 +
3 +[![NPM Version][npm-version-image]][npm-url]
4 +[![NPM Downloads][npm-downloads-image]][npm-url]
5 +[![Node.js Version][node-version-image]][node-version-url]
6 +[![Build Status][travis-image]][travis-url]
7 +[![Test Coverage][coveralls-image]][coveralls-url]
8 +
9 +Execute a listener when a response is about to write headers.
10 +
11 +## Installation
12 +
13 +This is a [Node.js](https://nodejs.org/en/) module available through the
14 +[npm registry](https://www.npmjs.com/). Installation is done using the
15 +[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
16 +
17 +```sh
18 +$ npm install on-headers
19 +```
20 +
21 +## API
22 +
23 +<!-- eslint-disable no-unused-vars -->
24 +
25 +```js
26 +var onHeaders = require('on-headers')
27 +```
28 +
29 +### onHeaders(res, listener)
30 +
31 +This will add the listener `listener` to fire when headers are emitted for `res`.
32 +The listener is passed the `response` object as it's context (`this`). Headers are
33 +considered to be emitted only once, right before they are sent to the client.
34 +
35 +When this is called multiple times on the same `res`, the `listener`s are fired
36 +in the reverse order they were added.
37 +
38 +## Examples
39 +
40 +```js
41 +var http = require('http')
42 +var onHeaders = require('on-headers')
43 +
44 +http
45 + .createServer(onRequest)
46 + .listen(3000)
47 +
48 +function addPoweredBy () {
49 + // set if not set by end of request
50 + if (!this.getHeader('X-Powered-By')) {
51 + this.setHeader('X-Powered-By', 'Node.js')
52 + }
53 +}
54 +
55 +function onRequest (req, res) {
56 + onHeaders(res, addPoweredBy)
57 +
58 + res.setHeader('Content-Type', 'text/plain')
59 + res.end('hello!')
60 +}
61 +```
62 +
63 +## Testing
64 +
65 +```sh
66 +$ npm test
67 +```
68 +
69 +## License
70 +
71 +[MIT](LICENSE)
72 +
73 +[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/on-headers/master
74 +[coveralls-url]: https://coveralls.io/r/jshttp/on-headers?branch=master
75 +[node-version-image]: https://badgen.net/npm/node/on-headers
76 +[node-version-url]: https://nodejs.org/en/download
77 +[npm-downloads-image]: https://badgen.net/npm/dm/on-headers
78 +[npm-url]: https://npmjs.org/package/on-headers
79 +[npm-version-image]: https://badgen.net/npm/v/on-headers
80 +[travis-image]: https://badgen.net/travis/jshttp/on-headers/master
81 +[travis-url]: https://travis-ci.org/jshttp/on-headers
1 +/*!
2 + * on-headers
3 + * Copyright(c) 2014 Douglas Christopher Wilson
4 + * MIT Licensed
5 + */
6 +
7 +'use strict'
8 +
9 +/**
10 + * Module exports.
11 + * @public
12 + */
13 +
14 +module.exports = onHeaders
15 +
16 +/**
17 + * Create a replacement writeHead method.
18 + *
19 + * @param {function} prevWriteHead
20 + * @param {function} listener
21 + * @private
22 + */
23 +
24 +function createWriteHead (prevWriteHead, listener) {
25 + var fired = false
26 +
27 + // return function with core name and argument list
28 + return function writeHead (statusCode) {
29 + // set headers from arguments
30 + var args = setWriteHeadHeaders.apply(this, arguments)
31 +
32 + // fire listener
33 + if (!fired) {
34 + fired = true
35 + listener.call(this)
36 +
37 + // pass-along an updated status code
38 + if (typeof args[0] === 'number' && this.statusCode !== args[0]) {
39 + args[0] = this.statusCode
40 + args.length = 1
41 + }
42 + }
43 +
44 + return prevWriteHead.apply(this, args)
45 + }
46 +}
47 +
48 +/**
49 + * Execute a listener when a response is about to write headers.
50 + *
51 + * @param {object} res
52 + * @return {function} listener
53 + * @public
54 + */
55 +
56 +function onHeaders (res, listener) {
57 + if (!res) {
58 + throw new TypeError('argument res is required')
59 + }
60 +
61 + if (typeof listener !== 'function') {
62 + throw new TypeError('argument listener must be a function')
63 + }
64 +
65 + res.writeHead = createWriteHead(res.writeHead, listener)
66 +}
67 +
68 +/**
69 + * Set headers contained in array on the response object.
70 + *
71 + * @param {object} res
72 + * @param {array} headers
73 + * @private
74 + */
75 +
76 +function setHeadersFromArray (res, headers) {
77 + for (var i = 0; i < headers.length; i++) {
78 + res.setHeader(headers[i][0], headers[i][1])
79 + }
80 +}
81 +
82 +/**
83 + * Set headers contained in object on the response object.
84 + *
85 + * @param {object} res
86 + * @param {object} headers
87 + * @private
88 + */
89 +
90 +function setHeadersFromObject (res, headers) {
91 + var keys = Object.keys(headers)
92 + for (var i = 0; i < keys.length; i++) {
93 + var k = keys[i]
94 + if (k) res.setHeader(k, headers[k])
95 + }
96 +}
97 +
98 +/**
99 + * Set headers and other properties on the response object.
100 + *
101 + * @param {number} statusCode
102 + * @private
103 + */
104 +
105 +function setWriteHeadHeaders (statusCode) {
106 + var length = arguments.length
107 + var headerIndex = length > 1 && typeof arguments[1] === 'string'
108 + ? 2
109 + : 1
110 +
111 + var headers = length >= headerIndex + 1
112 + ? arguments[headerIndex]
113 + : undefined
114 +
115 + this.statusCode = statusCode
116 +
117 + if (Array.isArray(headers)) {
118 + // handle array case
119 + setHeadersFromArray(this, headers)
120 + } else if (headers) {
121 + // handle object case
122 + setHeadersFromObject(this, headers)
123 + }
124 +
125 + // copy leading arguments
126 + var args = new Array(Math.min(length, headerIndex))
127 + for (var i = 0; i < args.length; i++) {
128 + args[i] = arguments[i]
129 + }
130 +
131 + return args
132 +}
1 +{
2 + "_from": "on-headers@~1.0.2",
3 + "_id": "on-headers@1.0.2",
4 + "_inBundle": false,
5 + "_integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
6 + "_location": "/on-headers",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "on-headers@~1.0.2",
12 + "name": "on-headers",
13 + "escapedName": "on-headers",
14 + "rawSpec": "~1.0.2",
15 + "saveSpec": null,
16 + "fetchSpec": "~1.0.2"
17 + },
18 + "_requiredBy": [
19 + "/express-session"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
22 + "_shasum": "772b0ae6aaa525c399e489adfad90c403eb3c28f",
23 + "_spec": "on-headers@~1.0.2",
24 + "_where": "C:\\Users\\fheld\\Desktop\\khuhub\\mapmory\\Mapmory\\node_modules\\express-session",
25 + "author": {
26 + "name": "Douglas Christopher Wilson",
27 + "email": "doug@somethingdoug.com"
28 + },
29 + "bugs": {
30 + "url": "https://github.com/jshttp/on-headers/issues"
31 + },
32 + "bundleDependencies": false,
33 + "deprecated": false,
34 + "description": "Execute a listener when a response is about to write headers",
35 + "devDependencies": {
36 + "eslint": "5.14.1",
37 + "eslint-config-standard": "12.0.0",
38 + "eslint-plugin-import": "2.16.0",
39 + "eslint-plugin-markdown": "1.0.0",
40 + "eslint-plugin-node": "8.0.1",
41 + "eslint-plugin-promise": "4.0.1",
42 + "eslint-plugin-standard": "4.0.0",
43 + "istanbul": "0.4.5",
44 + "mocha": "6.0.1",
45 + "supertest": "3.4.2"
46 + },
47 + "engines": {
48 + "node": ">= 0.8"
49 + },
50 + "files": [
51 + "LICENSE",
52 + "HISTORY.md",
53 + "README.md",
54 + "index.js"
55 + ],
56 + "homepage": "https://github.com/jshttp/on-headers#readme",
57 + "keywords": [
58 + "event",
59 + "headers",
60 + "http",
61 + "onheaders"
62 + ],
63 + "license": "MIT",
64 + "name": "on-headers",
65 + "repository": {
66 + "type": "git",
67 + "url": "git+https://github.com/jshttp/on-headers.git"
68 + },
69 + "scripts": {
70 + "lint": "eslint --plugin markdown --ext js,md .",
71 + "test": "mocha --reporter spec --bail --check-leaks test/",
72 + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
73 + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/",
74 + "version": "node scripts/version-history.js && git add HISTORY.md"
75 + },
76 + "version": "1.0.2"
77 +}
1 +1.0.0 / 2016-01-17
2 +==================
3 +
4 + * Initial release
1 +The MIT License (MIT)
2 +
3 +Copyright (c) 2016 Douglas Christopher Wilson <doug@somethingdoug.com>
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +# random-bytes
2 +
3 +[![NPM Version][npm-image]][npm-url]
4 +[![NPM Downloads][downloads-image]][downloads-url]
5 +[![Node.js Version][node-version-image]][node-version-url]
6 +[![Build Status][travis-image]][travis-url]
7 +[![Test Coverage][coveralls-image]][coveralls-url]
8 +
9 +Generate strong pseudo-random bytes.
10 +
11 +This module is a simple wrapper around the Node.js core `crypto.randomBytes` API,
12 +with the following additions:
13 +
14 + * A `Promise` interface for environments with promises.
15 + * For Node.js versions that do not wait for the PRNG to be seeded, this module
16 + will wait a bit.
17 +
18 +## Installation
19 +
20 +```sh
21 +$ npm install random-bytes
22 +```
23 +
24 +## API
25 +
26 +```js
27 +var randomBytes = require('random-bytes')
28 +```
29 +
30 +### randomBytes(size, callback)
31 +
32 +Generates strong pseudo-random bytes. The `size` argument is a number indicating
33 +the number of bytes to generate.
34 +
35 +```js
36 +randomBytes(12, function (error, bytes) {
37 + if (error) throw error
38 + // do something with the bytes
39 +})
40 +```
41 +
42 +### randomBytes(size)
43 +
44 +Generates strong pseudo-random bytes and return a `Promise`. The `size` argument is
45 +a number indicating the number of bytes to generate.
46 +
47 +**Note**: To use promises in Node.js _prior to 0.12_, promises must be
48 +"polyfilled" using `global.Promise = require('bluebird')`.
49 +
50 +```js
51 +randomBytes(18).then(function (string) {
52 + // do something with the string
53 +})
54 +```
55 +
56 +### randomBytes.sync(size)
57 +
58 +A synchronous version of above.
59 +
60 +```js
61 +var bytes = randomBytes.sync(18)
62 +```
63 +
64 +## License
65 +
66 +[MIT](LICENSE)
67 +
68 +[npm-image]: https://img.shields.io/npm/v/random-bytes.svg
69 +[npm-url]: https://npmjs.org/package/random-bytes
70 +[node-version-image]: https://img.shields.io/node/v/random-bytes.svg
71 +[node-version-url]: http://nodejs.org/download/
72 +[travis-image]: https://img.shields.io/travis/crypto-utils/random-bytes/master.svg
73 +[travis-url]: https://travis-ci.org/crypto-utils/random-bytes
74 +[coveralls-image]: https://img.shields.io/coveralls/crypto-utils/random-bytes/master.svg
75 +[coveralls-url]: https://coveralls.io/r/crypto-utils/random-bytes?branch=master
76 +[downloads-image]: https://img.shields.io/npm/dm/random-bytes.svg
77 +[downloads-url]: https://npmjs.org/package/random-bytes
1 +/*!
2 + * random-bytes
3 + * Copyright(c) 2016 Douglas Christopher Wilson
4 + * MIT Licensed
5 + */
6 +
7 +'use strict'
8 +
9 +/**
10 + * Module dependencies.
11 + * @private
12 + */
13 +
14 +var crypto = require('crypto')
15 +
16 +/**
17 + * Module variables.
18 + * @private
19 + */
20 +
21 +var generateAttempts = crypto.randomBytes === crypto.pseudoRandomBytes ? 1 : 3
22 +
23 +/**
24 + * Module exports.
25 + * @public
26 + */
27 +
28 +module.exports = randomBytes
29 +module.exports.sync = randomBytesSync
30 +
31 +/**
32 + * Generates strong pseudo-random bytes.
33 + *
34 + * @param {number} size
35 + * @param {function} [callback]
36 + * @return {Promise}
37 + * @public
38 + */
39 +
40 +function randomBytes(size, callback) {
41 + // validate callback is a function, if provided
42 + if (callback !== undefined && typeof callback !== 'function') {
43 + throw new TypeError('argument callback must be a function')
44 + }
45 +
46 + // require the callback without promises
47 + if (!callback && !global.Promise) {
48 + throw new TypeError('argument callback is required')
49 + }
50 +
51 + if (callback) {
52 + // classic callback style
53 + return generateRandomBytes(size, generateAttempts, callback)
54 + }
55 +
56 + return new Promise(function executor(resolve, reject) {
57 + generateRandomBytes(size, generateAttempts, function onRandomBytes(err, str) {
58 + if (err) return reject(err)
59 + resolve(str)
60 + })
61 + })
62 +}
63 +
64 +/**
65 + * Generates strong pseudo-random bytes sync.
66 + *
67 + * @param {number} size
68 + * @return {Buffer}
69 + * @public
70 + */
71 +
72 +function randomBytesSync(size) {
73 + var err = null
74 +
75 + for (var i = 0; i < generateAttempts; i++) {
76 + try {
77 + return crypto.randomBytes(size)
78 + } catch (e) {
79 + err = e
80 + }
81 + }
82 +
83 + throw err
84 +}
85 +
86 +/**
87 + * Generates strong pseudo-random bytes.
88 + *
89 + * @param {number} size
90 + * @param {number} attempts
91 + * @param {function} callback
92 + * @private
93 + */
94 +
95 +function generateRandomBytes(size, attempts, callback) {
96 + crypto.randomBytes(size, function onRandomBytes(err, buf) {
97 + if (!err) return callback(null, buf)
98 + if (!--attempts) return callback(err)
99 + setTimeout(generateRandomBytes.bind(null, size, attempts, callback), 10)
100 + })
101 +}
1 +{
2 + "_from": "random-bytes@~1.0.0",
3 + "_id": "random-bytes@1.0.0",
4 + "_inBundle": false,
5 + "_integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=",
6 + "_location": "/random-bytes",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "random-bytes@~1.0.0",
12 + "name": "random-bytes",
13 + "escapedName": "random-bytes",
14 + "rawSpec": "~1.0.0",
15 + "saveSpec": null,
16 + "fetchSpec": "~1.0.0"
17 + },
18 + "_requiredBy": [
19 + "/uid-safe"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
22 + "_shasum": "4f68a1dc0ae58bd3fb95848c30324db75d64360b",
23 + "_spec": "random-bytes@~1.0.0",
24 + "_where": "C:\\Users\\fheld\\Desktop\\khuhub\\mapmory\\Mapmory\\node_modules\\uid-safe",
25 + "bugs": {
26 + "url": "https://github.com/crypto-utils/random-bytes/issues"
27 + },
28 + "bundleDependencies": false,
29 + "contributors": [
30 + {
31 + "name": "Douglas Christopher Wilson",
32 + "email": "doug@somethingdoug.com"
33 + }
34 + ],
35 + "deprecated": false,
36 + "description": "URL and cookie safe UIDs",
37 + "devDependencies": {
38 + "bluebird": "3.1.1",
39 + "istanbul": "0.4.2",
40 + "mocha": "2.3.4",
41 + "proxyquire": "1.2.0"
42 + },
43 + "engines": {
44 + "node": ">= 0.8"
45 + },
46 + "files": [
47 + "LICENSE",
48 + "HISTORY.md",
49 + "README.md",
50 + "index.js"
51 + ],
52 + "homepage": "https://github.com/crypto-utils/random-bytes#readme",
53 + "keywords": [
54 + "bytes",
55 + "generator",
56 + "random",
57 + "safe"
58 + ],
59 + "license": "MIT",
60 + "name": "random-bytes",
61 + "repository": {
62 + "type": "git",
63 + "url": "git+https://github.com/crypto-utils/random-bytes.git"
64 + },
65 + "scripts": {
66 + "test": "mocha --trace-deprecation --reporter spec --bail --check-leaks test/",
67 + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --trace-deprecation --reporter dot --check-leaks test/",
68 + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --trace-deprecation --reporter spec --check-leaks test/"
69 + },
70 + "version": "1.0.0"
71 +}
1 +2.1.5 / 2017-08-02
2 +==================
3 +
4 + * perf: remove only trailing `=`
5 +
6 +2.1.4 / 2017-03-02
7 +==================
8 +
9 + * Remove `base64-url` dependency
10 +
11 +2.1.3 / 2016-10-30
12 +==================
13 +
14 + * deps: base64-url@1.3.3
15 +
16 +2.1.2 / 2016-08-15
17 +==================
18 +
19 + * deps: base64-url@1.3.2
20 +
21 +2.1.1 / 2016-05-04
22 +==================
23 +
24 + * deps: base64-url@1.2.2
25 +
26 +2.1.0 / 2016-01-17
27 +==================
28 +
29 + * Use `random-bytes` for byte source
30 +
31 +2.0.0 / 2015-05-08
32 +==================
33 +
34 + * Use global `Promise` when returning a promise
35 +
36 +1.1.0 / 2015-02-01
37 +==================
38 +
39 + * Use `crypto.randomBytes`, if available
40 + * deps: base64-url@1.2.1
41 +
42 +1.0.3 / 2015-01-31
43 +==================
44 +
45 + * Fix error branch that would throw
46 + * deps: base64-url@1.2.0
47 +
48 +1.0.2 / 2015-01-08
49 +==================
50 +
51 + * Remove dependency on `mz`
52 +
53 +1.0.1 / 2014-06-18
54 +==================
55 +
56 + * Remove direct `bluebird` dependency
57 +
58 +1.0.0 / 2014-06-18
59 +==================
60 +
61 + * Initial release
1 +The MIT License (MIT)
2 +
3 +Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
4 +Copyright (c) 2015-2017 Douglas Christopher Wilson <doug@somethingdoug.com>
5 +
6 +Permission is hereby granted, free of charge, to any person obtaining a copy
7 +of this software and associated documentation files (the "Software"), to deal
8 +in the Software without restriction, including without limitation the rights
9 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 +copies of the Software, and to permit persons to whom the Software is
11 +furnished to do so, subject to the following conditions:
12 +
13 +The above copyright notice and this permission notice shall be included in
14 +all copies or substantial portions of the Software.
15 +
16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 +THE SOFTWARE.
1 +# uid-safe
2 +
3 +[![NPM Version][npm-image]][npm-url]
4 +[![NPM Downloads][downloads-image]][downloads-url]
5 +[![Node.js Version][node-version-image]][node-version-url]
6 +[![Build Status][travis-image]][travis-url]
7 +[![Test Coverage][coveralls-image]][coveralls-url]
8 +
9 +URL and cookie safe UIDs
10 +
11 +Create cryptographically secure UIDs safe for both cookie and URL usage.
12 +This is in contrast to modules such as [rand-token](https://www.npmjs.com/package/rand-token)
13 +and [uid2](https://www.npmjs.com/package/uid2) whose UIDs are actually skewed
14 +due to the use of `%` and unnecessarily truncate the UID.
15 +Use this if you could still use UIDs with `-` and `_` in them.
16 +
17 +## Installation
18 +
19 +```sh
20 +$ npm install uid-safe
21 +```
22 +
23 +## API
24 +
25 +```js
26 +var uid = require('uid-safe')
27 +```
28 +
29 +### uid(byteLength, callback)
30 +
31 +Asynchronously create a UID with a specific byte length. Because `base64`
32 +encoding is used underneath, this is not the string length. For example,
33 +to create a UID of length 24, you want a byte length of 18.
34 +
35 +```js
36 +uid(18, function (err, string) {
37 + if (err) throw err
38 + // do something with the string
39 +})
40 +```
41 +
42 +### uid(byteLength)
43 +
44 +Asynchronously create a UID with a specific byte length and return a
45 +`Promise`.
46 +
47 +**Note**: To use promises in Node.js _prior to 0.12_, promises must be
48 +"polyfilled" using `global.Promise = require('bluebird')`.
49 +
50 +```js
51 +uid(18).then(function (string) {
52 + // do something with the string
53 +})
54 +```
55 +
56 +### uid.sync(byteLength)
57 +
58 +A synchronous version of above.
59 +
60 +```js
61 +var string = uid.sync(18)
62 +```
63 +
64 +## License
65 +
66 +[MIT](LICENSE)
67 +
68 +[npm-image]: https://img.shields.io/npm/v/uid-safe.svg
69 +[npm-url]: https://npmjs.org/package/uid-safe
70 +[node-version-image]: https://img.shields.io/node/v/uid-safe.svg
71 +[node-version-url]: https://nodejs.org/en/download/
72 +[travis-image]: https://img.shields.io/travis/crypto-utils/uid-safe/master.svg
73 +[travis-url]: https://travis-ci.org/crypto-utils/uid-safe
74 +[coveralls-image]: https://img.shields.io/coveralls/crypto-utils/uid-safe/master.svg
75 +[coveralls-url]: https://coveralls.io/r/crypto-utils/uid-safe?branch=master
76 +[downloads-image]: https://img.shields.io/npm/dm/uid-safe.svg
77 +[downloads-url]: https://npmjs.org/package/uid-safe
1 +/*!
2 + * uid-safe
3 + * Copyright(c) 2014 Jonathan Ong
4 + * Copyright(c) 2015-2017 Douglas Christopher Wilson
5 + * MIT Licensed
6 + */
7 +
8 +'use strict'
9 +
10 +/**
11 + * Module dependencies.
12 + * @private
13 + */
14 +
15 +var randomBytes = require('random-bytes')
16 +
17 +/**
18 + * Module variables.
19 + * @private
20 + */
21 +
22 +var EQUAL_END_REGEXP = /=+$/
23 +var PLUS_GLOBAL_REGEXP = /\+/g
24 +var SLASH_GLOBAL_REGEXP = /\//g
25 +
26 +/**
27 + * Module exports.
28 + * @public
29 + */
30 +
31 +module.exports = uid
32 +module.exports.sync = uidSync
33 +
34 +/**
35 + * Create a unique ID.
36 + *
37 + * @param {number} length
38 + * @param {function} [callback]
39 + * @return {Promise}
40 + * @public
41 + */
42 +
43 +function uid (length, callback) {
44 + // validate callback is a function, if provided
45 + if (callback !== undefined && typeof callback !== 'function') {
46 + throw new TypeError('argument callback must be a function')
47 + }
48 +
49 + // require the callback without promises
50 + if (!callback && !global.Promise) {
51 + throw new TypeError('argument callback is required')
52 + }
53 +
54 + if (callback) {
55 + // classic callback style
56 + return generateUid(length, callback)
57 + }
58 +
59 + return new Promise(function executor (resolve, reject) {
60 + generateUid(length, function onUid (err, str) {
61 + if (err) return reject(err)
62 + resolve(str)
63 + })
64 + })
65 +}
66 +
67 +/**
68 + * Create a unique ID sync.
69 + *
70 + * @param {number} length
71 + * @return {string}
72 + * @public
73 + */
74 +
75 +function uidSync (length) {
76 + return toString(randomBytes.sync(length))
77 +}
78 +
79 +/**
80 + * Generate a unique ID string.
81 + *
82 + * @param {number} length
83 + * @param {function} callback
84 + * @private
85 + */
86 +
87 +function generateUid (length, callback) {
88 + randomBytes(length, function (err, buf) {
89 + if (err) return callback(err)
90 + callback(null, toString(buf))
91 + })
92 +}
93 +
94 +/**
95 + * Change a Buffer into a string.
96 + *
97 + * @param {Buffer} buf
98 + * @return {string}
99 + * @private
100 + */
101 +
102 +function toString (buf) {
103 + return buf.toString('base64')
104 + .replace(EQUAL_END_REGEXP, '')
105 + .replace(PLUS_GLOBAL_REGEXP, '-')
106 + .replace(SLASH_GLOBAL_REGEXP, '_')
107 +}
1 +{
2 + "_from": "uid-safe@~2.1.5",
3 + "_id": "uid-safe@2.1.5",
4 + "_inBundle": false,
5 + "_integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
6 + "_location": "/uid-safe",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "uid-safe@~2.1.5",
12 + "name": "uid-safe",
13 + "escapedName": "uid-safe",
14 + "rawSpec": "~2.1.5",
15 + "saveSpec": null,
16 + "fetchSpec": "~2.1.5"
17 + },
18 + "_requiredBy": [
19 + "/express-session"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
22 + "_shasum": "2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a",
23 + "_spec": "uid-safe@~2.1.5",
24 + "_where": "C:\\Users\\fheld\\Desktop\\khuhub\\mapmory\\Mapmory\\node_modules\\express-session",
25 + "bugs": {
26 + "url": "https://github.com/crypto-utils/uid-safe/issues"
27 + },
28 + "bundleDependencies": false,
29 + "contributors": [
30 + {
31 + "name": "Douglas Christopher Wilson",
32 + "email": "doug@somethingdoug.com"
33 + },
34 + {
35 + "name": "Jonathan Ong",
36 + "email": "me@jongleberry.com",
37 + "url": "http://jongleberry.com"
38 + }
39 + ],
40 + "dependencies": {
41 + "random-bytes": "~1.0.0"
42 + },
43 + "deprecated": false,
44 + "description": "URL and cookie safe UIDs",
45 + "devDependencies": {
46 + "bluebird": "3.5.0",
47 + "eslint": "3.19.0",
48 + "eslint-config-standard": "10.2.1",
49 + "eslint-plugin-import": "2.7.0",
50 + "eslint-plugin-node": "5.1.1",
51 + "eslint-plugin-promise": "3.5.0",
52 + "eslint-plugin-standard": "3.0.1",
53 + "istanbul": "0.4.5",
54 + "mocha": "2.5.3"
55 + },
56 + "engines": {
57 + "node": ">= 0.8"
58 + },
59 + "files": [
60 + "LICENSE",
61 + "HISTORY.md",
62 + "README.md",
63 + "index.js"
64 + ],
65 + "homepage": "https://github.com/crypto-utils/uid-safe#readme",
66 + "keywords": [
67 + "random",
68 + "generator",
69 + "uid",
70 + "safe"
71 + ],
72 + "license": "MIT",
73 + "name": "uid-safe",
74 + "repository": {
75 + "type": "git",
76 + "url": "git+https://github.com/crypto-utils/uid-safe.git"
77 + },
78 + "scripts": {
79 + "lint": "eslint .",
80 + "test": "mocha --trace-deprecation --reporter spec --bail --check-leaks test/",
81 + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --trace-deprecation --reporter dot --check-leaks test/",
82 + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --trace-deprecation --reporter spec --check-leaks test/"
83 + },
84 + "version": "2.1.5"
85 +}
...@@ -148,6 +148,33 @@ ...@@ -148,6 +148,33 @@
148 "vary": "~1.1.2" 148 "vary": "~1.1.2"
149 } 149 }
150 }, 150 },
151 + "express-session": {
152 + "version": "1.17.1",
153 + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz",
154 + "integrity": "sha512-UbHwgqjxQZJiWRTMyhvWGvjBQduGCSBDhhZXYenziMFjxst5rMV+aJZ6hKPHZnPyHGsrqRICxtX8jtEbm/z36Q==",
155 + "requires": {
156 + "cookie": "0.4.0",
157 + "cookie-signature": "1.0.6",
158 + "debug": "2.6.9",
159 + "depd": "~2.0.0",
160 + "on-headers": "~1.0.2",
161 + "parseurl": "~1.3.3",
162 + "safe-buffer": "5.2.0",
163 + "uid-safe": "~2.1.5"
164 + },
165 + "dependencies": {
166 + "depd": {
167 + "version": "2.0.0",
168 + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
169 + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
170 + },
171 + "safe-buffer": {
172 + "version": "5.2.0",
173 + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
174 + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
175 + }
176 + }
177 + },
151 "finalhandler": { 178 "finalhandler": {
152 "version": "1.1.2", 179 "version": "1.1.2",
153 "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 180 "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
...@@ -269,6 +296,11 @@ ...@@ -269,6 +296,11 @@
269 "ee-first": "1.1.1" 296 "ee-first": "1.1.1"
270 } 297 }
271 }, 298 },
299 + "on-headers": {
300 + "version": "1.0.2",
301 + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
302 + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA=="
303 + },
272 "parseurl": { 304 "parseurl": {
273 "version": "1.3.3", 305 "version": "1.3.3",
274 "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 306 "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
...@@ -298,6 +330,11 @@ ...@@ -298,6 +330,11 @@
298 "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 330 "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
299 "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 331 "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
300 }, 332 },
333 + "random-bytes": {
334 + "version": "1.0.0",
335 + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
336 + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs="
337 + },
301 "range-parser": { 338 "range-parser": {
302 "version": "1.2.1", 339 "version": "1.2.1",
303 "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 340 "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
...@@ -413,6 +450,14 @@ ...@@ -413,6 +450,14 @@
413 "mime-types": "~2.1.24" 450 "mime-types": "~2.1.24"
414 } 451 }
415 }, 452 },
453 + "uid-safe": {
454 + "version": "2.1.5",
455 + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
456 + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
457 + "requires": {
458 + "random-bytes": "~1.0.0"
459 + }
460 + },
416 "unpipe": { 461 "unpipe": {
417 "version": "1.0.0", 462 "version": "1.0.0",
418 "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 463 "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
11 "dependencies": { 11 "dependencies": {
12 "body-parser": "^1.19.0", 12 "body-parser": "^1.19.0",
13 "express": "^4.17.1", 13 "express": "^4.17.1",
14 + "express-session": "^1.17.1",
14 "mysql": "^2.18.1" 15 "mysql": "^2.18.1"
15 } 16 }
16 } 17 }
......