@smpx/koa-request 0.5.0 → 1.0.0
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 +97 -155
- 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,71 @@ 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
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
platform() {
|
|
796
|
-
if (!this._platform) {
|
|
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;
|
|
821
|
+
isMobile() {
|
|
822
|
+
return this.appInfo().deviceType === 'mobile';
|
|
812
823
|
}
|
|
813
824
|
|
|
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
|
-
}
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
subPlatform() {
|
|
843
|
-
if (!this._subPlatform) {
|
|
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;
|
|
825
|
+
isTablet() {
|
|
826
|
+
return this.appInfo().deviceType === 'tablet';
|
|
853
827
|
}
|
|
854
828
|
|
|
855
829
|
isDesktop() {
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
if (platform) {
|
|
859
|
-
if (platform === 'desktop') return true;
|
|
860
|
-
return false;
|
|
861
|
-
}
|
|
830
|
+
return !this.isMobile();
|
|
831
|
+
}
|
|
862
832
|
|
|
863
|
-
|
|
833
|
+
isAPI() {
|
|
834
|
+
return false;
|
|
864
835
|
}
|
|
865
836
|
|
|
866
837
|
/**
|
|
@@ -1152,14 +1123,6 @@ class Request {
|
|
|
1152
1123
|
return '/signup?next=' + encodeURIComponent(this.nextUrl());
|
|
1153
1124
|
}
|
|
1154
1125
|
|
|
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
1126
|
redirect(url, qs = true) {
|
|
1164
1127
|
if (qs === true) {
|
|
1165
1128
|
url = addQuery(url, this.ctx.querystring);
|
|
@@ -1402,27 +1365,6 @@ class Request {
|
|
|
1402
1365
|
}
|
|
1403
1366
|
}
|
|
1404
1367
|
|
|
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
1368
|
geoipLoc() {
|
|
1427
1369
|
if (this._giploc === undefined) {
|
|
1428
1370
|
this._giploc = GeoIP.getSync(this.ip()) || {};
|