@smpx/koa-request 0.5.0 → 1.0.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 +102 -153
- package/package.json +1 -1
package/Request.js
CHANGED
|
@@ -22,7 +22,6 @@ const TEN_YEARS = 10 * ONE_YEAR;
|
|
|
22
22
|
|
|
23
23
|
const PLATFORM_PARAM = 'platform';
|
|
24
24
|
const PLATFORM_COOKIE = 'platform';
|
|
25
|
-
const PLATFORM_COOKIE_DURATION = 4 * ONE_HOUR;
|
|
26
25
|
const APPINFO_PARAM = 'sm_app';
|
|
27
26
|
const APPINFO_COOKIE = 'sm_app';
|
|
28
27
|
const APPINFO_HEADER = 'sm-app';
|
|
@@ -399,7 +398,6 @@ class Request {
|
|
|
399
398
|
this.ctx.set('Content-Security-Policy', `frame-ancestors https://*.${domain}`);
|
|
400
399
|
}
|
|
401
400
|
|
|
402
|
-
this.handlePlatformModification();
|
|
403
401
|
if (!this.isAjax()) {
|
|
404
402
|
this.setUTMCookie();
|
|
405
403
|
this.setAffidCookie();
|
|
@@ -653,17 +651,17 @@ class Request {
|
|
|
653
651
|
_getAppInfoFromString(infoStr, separator = '#') {
|
|
654
652
|
if (!infoStr) return null;
|
|
655
653
|
// eslint-disable-next-line prefer-const
|
|
656
|
-
let [
|
|
657
|
-
|
|
654
|
+
let [os, appVersion, installId] = infoStr.split(separator);
|
|
655
|
+
os = os.toLowerCase();
|
|
658
656
|
|
|
659
657
|
const appInfo = {
|
|
660
|
-
|
|
658
|
+
os,
|
|
661
659
|
appVersion,
|
|
662
660
|
installId,
|
|
663
661
|
};
|
|
664
662
|
|
|
665
|
-
if (this.appPlatforms().has(
|
|
666
|
-
appInfo.
|
|
663
|
+
if (this.appPlatforms().has(os)) {
|
|
664
|
+
appInfo.appType = 'app';
|
|
667
665
|
}
|
|
668
666
|
|
|
669
667
|
return appInfo;
|
|
@@ -693,17 +691,75 @@ class Request {
|
|
|
693
691
|
return this._getAppInfoFromString(this.ctx.headers[APPINFO_HEADER]);
|
|
694
692
|
}
|
|
695
693
|
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
694
|
+
getAppInfoCustom() {
|
|
695
|
+
return null;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
_getDeviceTypeFromUA() {
|
|
699
|
+
const ua = this.parseUserAgent();
|
|
700
|
+
const deviceType = ua.device?.type;
|
|
701
|
+
if (deviceType === 'mobile') return 'mobile';
|
|
702
|
+
if (deviceType === 'tablet') return 'tablet';
|
|
703
|
+
return 'desktop';
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
_getDeviceType() {
|
|
707
|
+
const secHeader = this.ctx.headers['sec-ch-ua-mobile'];
|
|
708
|
+
if (secHeader) {
|
|
709
|
+
if (secHeader === '?1') return 'mobile';
|
|
710
|
+
return this._getDeviceTypeFromUA();
|
|
711
|
+
}
|
|
712
|
+
const vwCookie = this.cookie(VIEWPORT_WIDTH_COOKIE);
|
|
713
|
+
if (vwCookie) {
|
|
714
|
+
if (Number(vwCookie) <= 750) return 'mobile';
|
|
715
|
+
return this._getDeviceTypeFromUA();
|
|
716
|
+
}
|
|
717
|
+
return this._getDeviceTypeFromUA();
|
|
718
|
+
}
|
|
699
719
|
|
|
700
|
-
|
|
701
|
-
|
|
720
|
+
computeAppInfo() {
|
|
721
|
+
const ctx = this.ctx;
|
|
702
722
|
|
|
703
|
-
const
|
|
704
|
-
|
|
723
|
+
const appInfo1 = this.getAppInfoFromHeader() || {};
|
|
724
|
+
const appInfo2 = this.getAppInfoFromParam() || {};
|
|
725
|
+
const appInfo3 = this.getAppInfoFromUserAgent() || {};
|
|
726
|
+
const appInfo4 = this.getAppInfoCustom() || {};
|
|
705
727
|
|
|
706
|
-
|
|
728
|
+
const appInfo = {
|
|
729
|
+
installId: ctx.query.installId,
|
|
730
|
+
appVersion: ctx.query.appVersion,
|
|
731
|
+
...appInfo4,
|
|
732
|
+
...appInfo3,
|
|
733
|
+
...appInfo2,
|
|
734
|
+
...appInfo1,
|
|
735
|
+
};
|
|
736
|
+
|
|
737
|
+
let xPlatform = (
|
|
738
|
+
ctx.query[PLATFORM_PARAM] ||
|
|
739
|
+
this.cookie(PLATFORM_COOKIE) ||
|
|
740
|
+
ctx.headers['x-sm-platform']
|
|
741
|
+
);
|
|
742
|
+
if (xPlatform) {
|
|
743
|
+
xPlatform = xPlatform.toLowerCase();
|
|
744
|
+
if (xPlatform === 'mobile_app') {
|
|
745
|
+
if (!appInfo.deviceType) appInfo.deviceType = 'mobile';
|
|
746
|
+
if (!appInfo.appType) appInfo.appType = 'app';
|
|
747
|
+
}
|
|
748
|
+
else {
|
|
749
|
+
const os = xPlatform.match(/android|ios|wp|tizen|jio/i)?.[0];
|
|
750
|
+
if (os) {
|
|
751
|
+
if (!appInfo.deviceType) appInfo.deviceType = 'mobile';
|
|
752
|
+
if (!appInfo.appType) appInfo.appType = 'app';
|
|
753
|
+
if (!appInfo.os) appInfo.os = os.toLowerCase();
|
|
754
|
+
}
|
|
755
|
+
else if (!appInfo.deviceType) {
|
|
756
|
+
appInfo.deviceType = xPlatform.includes('mobile') ? 'mobile' : 'desktop';
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
else if (!appInfo.deviceType) {
|
|
761
|
+
appInfo.deviceType = this._getDeviceType();
|
|
762
|
+
}
|
|
707
763
|
}
|
|
708
764
|
|
|
709
765
|
/*
|
|
@@ -711,156 +767,78 @@ class Request {
|
|
|
711
767
|
* this means that you can have the url as sm_app=android
|
|
712
768
|
* and it'll automatically identify it as an android app
|
|
713
769
|
*/
|
|
714
|
-
appInfo(
|
|
770
|
+
appInfo() {
|
|
715
771
|
if (!this._appInfo) {
|
|
716
|
-
this._appInfo = this.
|
|
772
|
+
this._appInfo = this.computeAppInfo() || {};
|
|
717
773
|
}
|
|
718
|
-
return
|
|
774
|
+
return this._appInfo;
|
|
719
775
|
}
|
|
720
776
|
|
|
721
777
|
installId() {
|
|
722
|
-
return this.appInfo(
|
|
778
|
+
return this.appInfo().installId || '';
|
|
723
779
|
}
|
|
724
780
|
|
|
725
781
|
appVersion() {
|
|
726
|
-
return this.appInfo(
|
|
782
|
+
return this.appInfo().appVersion || '';
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
isApp() {
|
|
786
|
+
return this.appInfo().type === 'app';
|
|
727
787
|
}
|
|
728
788
|
|
|
729
789
|
isAndroidApp() {
|
|
730
|
-
return this.appInfo(
|
|
790
|
+
return this.isApp() && this.appInfo().os === 'android';
|
|
731
791
|
}
|
|
732
792
|
|
|
733
793
|
isIOSApp() {
|
|
734
|
-
return this.appInfo(
|
|
794
|
+
return this.isApp() && this.appInfo().os === 'ios';
|
|
735
795
|
}
|
|
736
796
|
|
|
737
797
|
isWPApp() {
|
|
738
|
-
return this.appInfo(
|
|
798
|
+
return this.isApp() && this.appInfo().os === 'wp';
|
|
739
799
|
}
|
|
740
800
|
|
|
741
801
|
isTizenApp() {
|
|
742
|
-
return this.appInfo(
|
|
802
|
+
return this.isApp() && this.appInfo().os === 'tizen';
|
|
743
803
|
}
|
|
744
804
|
|
|
745
805
|
isJIOApp() {
|
|
746
|
-
return this.appInfo(
|
|
806
|
+
return this.isApp() && this.appInfo().os === 'jio';
|
|
747
807
|
}
|
|
748
808
|
|
|
749
809
|
isMobileApp() {
|
|
750
|
-
|
|
751
|
-
const platform = this._platform;
|
|
752
|
-
if (platform) {
|
|
753
|
-
if (platform === 'mobile_app') return true;
|
|
754
|
-
return false;
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
return !!this.appInfo('isMobileApp');
|
|
810
|
+
return this.isApp() && this.isMobile();
|
|
758
811
|
}
|
|
759
812
|
|
|
760
813
|
isMobileWeb() {
|
|
761
|
-
|
|
762
|
-
const platform = this._platform;
|
|
763
|
-
if (platform) {
|
|
764
|
-
if (platform === 'mobile_web') return true;
|
|
765
|
-
return false;
|
|
766
|
-
}
|
|
767
|
-
|
|
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
|
-
}
|
|
783
|
-
}
|
|
784
|
-
return this._isMobileWeb;
|
|
814
|
+
return this.isMobile() && !this.isApp();
|
|
785
815
|
}
|
|
786
816
|
|
|
787
|
-
|
|
788
|
-
return this.
|
|
817
|
+
deviceType() {
|
|
818
|
+
return this.appInfo().deviceType || 'desktop';
|
|
789
819
|
}
|
|
790
820
|
|
|
791
|
-
|
|
792
|
-
return
|
|
821
|
+
isMobile() {
|
|
822
|
+
return this.appInfo().deviceType === 'mobile';
|
|
793
823
|
}
|
|
794
824
|
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
if (this.isMobileApp()) {
|
|
798
|
-
this._platform = 'mobile_app';
|
|
799
|
-
}
|
|
800
|
-
else if (this.isMobileWeb()) {
|
|
801
|
-
this._platform = 'mobile_web';
|
|
802
|
-
}
|
|
803
|
-
else if (this.isAPI()) {
|
|
804
|
-
this._platform = 'api';
|
|
805
|
-
}
|
|
806
|
-
else {
|
|
807
|
-
this._platform = 'desktop';
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
return this._platform;
|
|
825
|
+
isTablet() {
|
|
826
|
+
return this.appInfo().deviceType === 'tablet';
|
|
812
827
|
}
|
|
813
828
|
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
platform = handleArray(platform);
|
|
817
|
-
const appPlatform = platform.replace('_app', '');
|
|
818
|
-
|
|
819
|
-
if (this.appPlatforms().has(appPlatform)) {
|
|
820
|
-
this._platform = 'mobile_app';
|
|
821
|
-
this._subPlatform = `${appPlatform}_app`;
|
|
822
|
-
return false;
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
switch (platform) {
|
|
826
|
-
case 'mobile':
|
|
827
|
-
case 'mobile_web':
|
|
828
|
-
this._platform = 'mobile_web';
|
|
829
|
-
return true;
|
|
830
|
-
case 'www':
|
|
831
|
-
case 'desktop':
|
|
832
|
-
this._platform = 'desktop';
|
|
833
|
-
return true;
|
|
834
|
-
case 'mobile_app':
|
|
835
|
-
this._platform = 'mobile_app';
|
|
836
|
-
return true;
|
|
837
|
-
default:
|
|
838
|
-
return false;
|
|
839
|
-
}
|
|
829
|
+
isDesktop() {
|
|
830
|
+
return !this.isMobile();
|
|
840
831
|
}
|
|
841
832
|
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
const appPlatform = this.appInfo('platform');
|
|
845
|
-
if (appPlatform && this.isMobileApp()) {
|
|
846
|
-
this._subPlatform = `${appPlatform}_app`;
|
|
847
|
-
}
|
|
848
|
-
else {
|
|
849
|
-
this._subPlatform = this.platform();
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
return this._subPlatform;
|
|
833
|
+
isAPI() {
|
|
834
|
+
return false;
|
|
853
835
|
}
|
|
854
836
|
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
if (
|
|
859
|
-
|
|
860
|
-
return false;
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
return this.platform() === 'desktop';
|
|
837
|
+
platform() {
|
|
838
|
+
if (this.isApp()) return 'mobile_app';
|
|
839
|
+
if (this.isMobile()) return 'mobile_web';
|
|
840
|
+
if (this.isAPI()) return 'api';
|
|
841
|
+
return 'desktop';
|
|
864
842
|
}
|
|
865
843
|
|
|
866
844
|
/**
|
|
@@ -1152,14 +1130,6 @@ class Request {
|
|
|
1152
1130
|
return '/signup?next=' + encodeURIComponent(this.nextUrl());
|
|
1153
1131
|
}
|
|
1154
1132
|
|
|
1155
|
-
mobileUrl() {
|
|
1156
|
-
return addQuery(this.ctx.url, {[PLATFORM_PARAM]: 'mobile'});
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
|
-
desktopUrl() {
|
|
1160
|
-
return addQuery(this.ctx.url, {[PLATFORM_PARAM]: 'desktop'});
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
1133
|
redirect(url, qs = true) {
|
|
1164
1134
|
if (qs === true) {
|
|
1165
1135
|
url = addQuery(url, this.ctx.querystring);
|
|
@@ -1402,27 +1372,6 @@ class Request {
|
|
|
1402
1372
|
}
|
|
1403
1373
|
}
|
|
1404
1374
|
|
|
1405
|
-
handlePlatformModification() {
|
|
1406
|
-
let setPlatformCookie = false;
|
|
1407
|
-
if (!this.isMobileApp() && !this.isAjax()) {
|
|
1408
|
-
// don't change platform in mobile apps (and ajax requests) 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
|
-
}
|
|
1423
|
-
}
|
|
1424
|
-
}
|
|
1425
|
-
|
|
1426
1375
|
geoipLoc() {
|
|
1427
1376
|
if (this._giploc === undefined) {
|
|
1428
1377
|
this._giploc = GeoIP.getSync(this.ip()) || {};
|