@smpx/koa-request 0.2.8 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Request.js CHANGED
@@ -10,6 +10,8 @@ const enableBasicAuth = require('./basicAuth');
10
10
  const enableStaticPaths = require('./staticPaths');
11
11
  const enableBotBanning = require('./botBanning');
12
12
 
13
+ const {setLogger, logError} = require('./logger');
14
+
13
15
  const uaParser = new UAParser();
14
16
 
15
17
  const ONE_HOUR = 3600 * 1000;
@@ -37,6 +39,7 @@ const COOKIEID_COOKIE = 'id';
37
39
  const COOKIE_PARAM_PREFIX = '_ck_';
38
40
  const USER_TOKEN_COOKIE = 'utok';
39
41
  const FLASH_COOKIE = 'flash';
42
+ const VIEWPORT_WIDTH_COOKIE = 'vw';
40
43
  // these cookies are httpOnly, should not be readable from js
41
44
  const SENSITIVE_COOKIES = [USER_TOKEN_COOKIE, COOKIEID_COOKIE, SESSIONID_COOKIE];
42
45
 
@@ -122,19 +125,25 @@ function getIntegerKey(key) {
122
125
  }
123
126
 
124
127
  function addQuery(url, query = {}) {
125
- const uri = new URL(url, 'http://localhost');
126
- if (typeof query === 'string') {
127
- query = new URLSearchParams(query);
128
- for (const [key, val] of query) {
129
- uri.searchParams.set(key, val);
128
+ try {
129
+ const uri = new URL(url, 'http://localhost');
130
+ if (typeof query === 'string') {
131
+ query = new URLSearchParams(query);
132
+ for (const [key, val] of query) {
133
+ uri.searchParams.set(key, val);
134
+ }
130
135
  }
131
- }
132
- else {
133
- for (const [key, val] of Object.entries(query)) {
134
- uri.searchParams.set(key, val);
136
+ else {
137
+ for (const [key, val] of Object.entries(query)) {
138
+ uri.searchParams.set(key, val);
139
+ }
135
140
  }
141
+ return `${uri.pathname}${uri.search}`;
142
+ }
143
+ catch (e) {
144
+ logError(e);
145
+ return url;
136
146
  }
137
- return `${uri.pathname}${uri.search}`;
138
147
  }
139
148
 
140
149
  const isProduction = (process.env.NODE_ENV === 'production');
@@ -756,9 +765,21 @@ class Request {
756
765
  return false;
757
766
  }
758
767
 
759
- if (!this._isMobileWeb) {
760
- const ua = this.parseUserAgent();
761
- this._isMobileWeb = (ua && ua.device && ua.device.type === 'mobile') || false;
768
+ if (this._isMobileWeb == null) {
769
+ const secHeader = this.ctx.headers['sec-ch-ua-mobile'];
770
+ if (secHeader) {
771
+ this._isMobileWeb = secHeader === '?1';
772
+ }
773
+ else {
774
+ const vwCookie = this.cookie(VIEWPORT_WIDTH_COOKIE);
775
+ if (vwCookie) {
776
+ this._isMobileWeb = Number(vwCookie) <= 750;
777
+ }
778
+ else {
779
+ const ua = this.parseUserAgent();
780
+ this._isMobileWeb = (ua && ua.device && ua.device.type === 'mobile') || false;
781
+ }
782
+ }
762
783
  }
763
784
  return this._isMobileWeb;
764
785
  }
@@ -767,6 +788,10 @@ class Request {
767
788
  return this.isMobileApp() || this.isMobileWeb();
768
789
  }
769
790
 
791
+ isAPI() {
792
+ return false;
793
+ }
794
+
770
795
  platform() {
771
796
  if (!this._platform) {
772
797
  if (this.isMobileApp()) {
@@ -1218,7 +1243,20 @@ class Request {
1218
1243
  };
1219
1244
  }
1220
1245
 
1221
- const refererUri = new URL(referer);
1246
+ let refererUri;
1247
+ try {
1248
+ refererUri = new URL(referer, 'http://localhost');
1249
+ }
1250
+ catch (e) {
1251
+ logError(e);
1252
+ return {
1253
+ name: '',
1254
+ source: 'direct',
1255
+ medium: 'direct',
1256
+ term: '',
1257
+ };
1258
+ }
1259
+
1222
1260
  let host = refererUri.hostname;
1223
1261
  const baseDomain = this.baseDomain();
1224
1262
 
@@ -1271,16 +1309,22 @@ class Request {
1271
1309
  * sets UTM cookies from a predefined url
1272
1310
  */
1273
1311
  setUTMCookieFromUrl(url) {
1274
- const uri = (url instanceof URL) ? url : new URL(url, 'http://localhost');
1275
- const params = uri.searchParams;
1276
- this.setUTMCookieFromQuery({
1277
- utm_source: params.get('utm_source'),
1278
- utm_medium: params.get('utm_medium'),
1279
- utm_campaign: params.get('utm_campaign'),
1280
- utm_term: params.get('utm_term'),
1281
- utm_content: params.get('utm_content'),
1282
- gclid: params.get('gclid'),
1283
- });
1312
+ try {
1313
+ const uri = (url instanceof URL) ? url : new URL(url, 'http://localhost');
1314
+ const params = uri.searchParams;
1315
+ this.setUTMCookieFromQuery({
1316
+ utm_source: params.get('utm_source'),
1317
+ utm_medium: params.get('utm_medium'),
1318
+ utm_campaign: params.get('utm_campaign'),
1319
+ utm_term: params.get('utm_term'),
1320
+ utm_content: params.get('utm_content'),
1321
+ gclid: params.get('gclid'),
1322
+ });
1323
+ }
1324
+ catch (e) {
1325
+ logError(e);
1326
+ // ignore error
1327
+ }
1284
1328
  }
1285
1329
 
1286
1330
  /**
@@ -1337,32 +1381,45 @@ class Request {
1337
1381
  }
1338
1382
 
1339
1383
  setAffidCookieFromUrl(url) {
1340
- const uri = (url instanceof URL) ? url : new URL(url, 'http://localhost');
1341
- const params = uri.searchParams;
1342
- const affid = params.get(AFFID_PARAM);
1343
- if (!affid) return;
1344
- const subaffid = params.get(SUBAFFID_PARAM);
1345
-
1346
- this.cookie(
1347
- AFFID_COOKIE,
1348
- joinCookieParts([affid, subaffid]), {
1349
- maxAge: AFFID_COOKIE_DURATION,
1350
- domain: '*',
1351
- },
1352
- );
1384
+ try {
1385
+ const uri = (url instanceof URL) ? url : new URL(url, 'http://localhost');
1386
+ const params = uri.searchParams;
1387
+ const affid = params.get(AFFID_PARAM);
1388
+ if (!affid) return;
1389
+ const subaffid = params.get(SUBAFFID_PARAM);
1390
+
1391
+ this.cookie(
1392
+ AFFID_COOKIE,
1393
+ joinCookieParts([affid, subaffid]), {
1394
+ maxAge: AFFID_COOKIE_DURATION,
1395
+ domain: '*',
1396
+ },
1397
+ );
1398
+ }
1399
+ catch (e) {
1400
+ logError(e);
1401
+ // ignore error
1402
+ }
1353
1403
  }
1354
1404
 
1355
1405
  handlePlatformModification() {
1356
- // don't change platform in mobile apps
1357
- if (this.isMobileApp()) return;
1358
-
1359
- const platform = this.ctx.query[PLATFORM_PARAM] || this.cookie(PLATFORM_COOKIE);
1360
- const setPlatformCookie = this.setPlatform(platform);
1361
- if (setPlatformCookie) {
1362
- this.cookie(PLATFORM_COOKIE, platform, {
1363
- maxAge: PLATFORM_COOKIE_DURATION,
1364
- domain: '*',
1365
- });
1406
+ let setPlatformCookie = false;
1407
+ if (!this.isMobileApp()) {
1408
+ // don't change platform in mobile apps from query or cookie
1409
+ const platform = this.ctx.query[PLATFORM_PARAM] || this.cookie(PLATFORM_COOKIE);
1410
+ setPlatformCookie = this.setPlatform(platform);
1411
+ if (setPlatformCookie) {
1412
+ this.cookie(PLATFORM_COOKIE, platform, {
1413
+ maxAge: PLATFORM_COOKIE_DURATION,
1414
+ domain: '*',
1415
+ });
1416
+ }
1417
+ }
1418
+ if (!setPlatformCookie) {
1419
+ const smPlatform = this.header('x-sm-platform');
1420
+ if (smPlatform) {
1421
+ this._platform = smPlatform;
1422
+ }
1366
1423
  }
1367
1424
  }
1368
1425
 
@@ -1479,7 +1536,7 @@ class Request {
1479
1536
  }
1480
1537
  catch (e) {
1481
1538
  this._flash = '';
1482
- console.error('Error parsing flash message', e);
1539
+ logError('Error parsing flash message', e);
1483
1540
  }
1484
1541
 
1485
1542
  this.cookie(FLASH_COOKIE, null);
@@ -1561,4 +1618,5 @@ class Request {
1561
1618
  }
1562
1619
  }
1563
1620
 
1621
+ Request.setLogger = setLogger;
1564
1622
  module.exports = Request;
package/basicAuth.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const auth = require('koa-basic-auth');
2
2
 
3
- module.exports = function enableBasicAuth(app, options = {}) {
3
+ module.exports = function enableBasicAuth(app, options) {
4
4
  if (!options || options.enabled === false) return;
5
5
 
6
6
  app.use(async (ctx, next) => {
package/botBanning.js CHANGED
@@ -26,7 +26,7 @@ function banned(ctx, email) {
26
26
  ctx.body = `<pre>Our system has detected unusual traffic from your ip ${ip}. Hence your ip has been banned temporarily.\n${emailStr}</pre>`;
27
27
  }
28
28
 
29
- module.exports = function enableBotBanning(app, options = {}) {
29
+ module.exports = function enableBotBanning(app, options) {
30
30
  if (!options || options.enabled === false) return;
31
31
 
32
32
  let userAgents = [];
package/logger.js ADDED
@@ -0,0 +1,22 @@
1
+ let globalLogger;
2
+
3
+ /**
4
+ * set logger
5
+ */
6
+ function setLogger(logger) {
7
+ globalLogger = logger;
8
+ }
9
+
10
+ function logError(...args) {
11
+ if (globalLogger !== undefined) {
12
+ if (globalLogger) globalLogger.error(...args);
13
+ }
14
+ else {
15
+ console.error(...args);
16
+ }
17
+ }
18
+
19
+ module.exports = {
20
+ setLogger,
21
+ logError,
22
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smpx/koa-request",
3
- "version": "0.2.8",
3
+ "version": "0.4.1",
4
4
  "description": "Handle basic tasks for koajs",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -30,12 +30,12 @@
30
30
  },
31
31
  "homepage": "https://github.com/smartprix/koa-request#readme",
32
32
  "dependencies": {
33
- "ip": "^1.1.5",
33
+ "ip": "^1.1.8",
34
34
  "koa-basic-auth": "^4.0.0",
35
- "koa-body": "^4.2.0",
35
+ "koa-body": "^5.0.0",
36
36
  "koa-send": "^5.0.1",
37
- "koa2-ratelimit": "^0.9.1",
38
- "maxmind": "^4.3.3",
37
+ "koa2-ratelimit": "^1.1.1",
38
+ "maxmind": "^4.3.6",
39
39
  "tar": "^6.1.11",
40
40
  "ua-parser-js": "^1.0.2"
41
41
  },
package/rateLimit.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const {RateLimit} = require('koa2-ratelimit');
2
2
 
3
- module.exports = function enableRateLimit(app, options = {}) {
3
+ module.exports = function enableRateLimit(app, options) {
4
4
  if (!options || options.enabled === false) return;
5
5
 
6
6
  const skip = options.skip;
package/staticPaths.js CHANGED
@@ -20,8 +20,8 @@ function getMiddleware(options) {
20
20
 
21
21
  if (options.path === '/') {
22
22
  // root requires special handling to check if extension denotes a static path
23
- const matches = ctx.path.match(/^\/(.*)\.(jpg|jpeg|gif|png|webp|avif|jxl|ico|css|js|mjs|json|ttf|otf|eot|woff|woff2|svg|svgz|xml|html|txt|ogg|ogv|mp4|av1|webm|rss|atom|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$/);
24
- if (!matches) {
23
+ const isStatic = /^\/(.*)\.(jpg|jpeg|gif|png|webp|avif|jxl|ico|css|js|mjs|json|ttf|otf|eot|woff|woff2|svg|svgz|xml|html|txt|ogg|ogv|mp4|av1|webm|rss|atom|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$/.test(ctx.path);
24
+ if (!isStatic) {
25
25
  await next();
26
26
  return;
27
27
  }
@@ -48,7 +48,7 @@ function getMiddleware(options) {
48
48
 
49
49
  if (options.immutable) {
50
50
  // return a 304 not modified response, as immutables can't be modified
51
- if (ctx.headers['if-modified-since']) {
51
+ if (ctx.headers['if-modified-since'] && !ctx.response.get('Cache-Control')) {
52
52
  ctx.status = 304;
53
53
  return;
54
54
  }