-
Notifications
You must be signed in to change notification settings - Fork 45
/
Copy pathindex.js
88 lines (88 loc) · 2.74 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*jshint node:true*/
'use strict';
module.exports = {
backend: function evercookieMiddlewareBackendFactory(opts) {
opts = opts || {};
var defaultOptionMap = {
etagCookieName: 'evercookie_etag',
cacheCookieName: 'evercookie_cache',
authPath: '/evercookie_auth.php',
pngPath: '/evercookie_png.php',
etagPath: '/evercookie_etag.php',
cachePath: '/evercookie_cache.php'
};
var optionMap = {};
for (var key in defaultOptionMap) {
var overidenValue = opts[key];
if (overidenValue) {
optionMap[key] = opts[key];
} else {
optionMap[key] = defaultOptionMap[key];
}
}
function evercookieMiddlewareBackend(req, res, next) {
var cookieValue;
switch (req.path) {
case optionMap.authPath:
try {
cookieValue = Buffer.from(
req.headers.authorization.split(' ')[1],
'base64'
)
.toString()
.split(':')[0];
} catch (e) {}
if (cookieValue) {
res.send(cookieValue);
return;
}
res.setHeader('WWW-Authenticate', 'Basic');
res.sendStatus(401);
return;
case optionMap.pngPath:
/**
* PNG cache is technically no difference than text cache, but adds much more overhead to encode and decode.
* Return 201 No content
*/
res.sendStatus(201);
return;
case optionMap.etagPath:
/**
* Port to NodeJS by TruongSinh <[email protected]>
* Defined by samy kamkar, https://github.com/samyk/evercookie/blob/master/evercookie_etag.php
*
* This is the server-side ETag software which tags a user by
* using the Etag HTTP header, as well as If-None-Match to check
* if the user has been tagged before.
*/
cookieValue = req.cookies[optionMap.etagCookieName];
if (!cookieValue) {
cookieValue = req.get('If-None-Match');
}
if (cookieValue) {
res.set('Etag', cookieValue);
res.send(cookieValue);
return;
}
res.sendStatus(304);
return;
case optionMap.cachePath:
cookieValue = req.cookies[optionMap.cacheCookieName];
if (cookieValue) {
res.set({
'Content-Type': 'text/html',
Expires: 'Tue, 31 Dec 2030 23:30:45 GMT',
'Cache-Control': 'private, max-age=630720000'
});
res.send(cookieValue);
return;
}
res.sendStatus(304);
return;
default:
next();
}
}
return evercookieMiddlewareBackend;
}
};