Skip to content

Commit ab398fd

Browse files
committed
Add version helpers to auth-next (#2910)
* Add version helper to auth-next * [AUTOMATED]: Prettier Code Styling * PR feedback
1 parent a49f744 commit ab398fd

File tree

4 files changed

+290
-0
lines changed

4 files changed

+290
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import { expect } from 'chai';
19+
import { getBrowserName, BrowserName } from './browser';
20+
21+
describe('getBrowserName', () => {
22+
it('should recognize Opera', () => {
23+
const userAgent =
24+
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36 OPR/36.0.2130.74';
25+
expect(getBrowserName(userAgent)).to.eq(BrowserName.OPERA);
26+
});
27+
28+
it('should recognize IE', () => {
29+
const userAgent =
30+
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C)';
31+
expect(getBrowserName(userAgent)).to.eq(BrowserName.IE);
32+
});
33+
34+
it('should recognize Edge', () => {
35+
const userAgent =
36+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240';
37+
expect(getBrowserName(userAgent)).to.eq(BrowserName.EDGE);
38+
});
39+
40+
it('should recognize Firefox', () => {
41+
const userAgent =
42+
'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:46.0) Gecko/20100101 Firefox/46.0';
43+
expect(getBrowserName(userAgent)).to.eq(BrowserName.FIREFOX);
44+
});
45+
46+
it('should recognize Silk', () => {
47+
const userAgent =
48+
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Silk/44.1.54 like Chrome/44.0.2403.63 Safari/537.36';
49+
expect(getBrowserName(userAgent)).to.eq(BrowserName.SILK);
50+
});
51+
52+
it('should recognize Safari', () => {
53+
const userAgent =
54+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11-4) AppleWebKit/601.5.17 (KHTML, like Gecko) Version/9.1 Safari/601.5.17';
55+
expect(getBrowserName(userAgent)).to.eq(BrowserName.SAFARI);
56+
});
57+
58+
it('should recognize Chrome', () => {
59+
const userAgent =
60+
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36';
61+
expect(getBrowserName(userAgent)).to.eq(BrowserName.CHROME);
62+
});
63+
64+
it('should recognize Android', () => {
65+
const userAgent =
66+
'Mozilla/5.0 (Linux; U; Android 4.0.3; ko-kr; LG-L160L Build/IML74K) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30';
67+
expect(getBrowserName(userAgent)).to.eq(BrowserName.ANDROID);
68+
});
69+
70+
it('should recognize Blackberry', () => {
71+
const userAgent =
72+
'Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.1.0.346 Mobile Safari/534.11+';
73+
expect(getBrowserName(userAgent)).to.eq(BrowserName.BLACKBERRY);
74+
});
75+
76+
it('should recognize IE Mobile', () => {
77+
const userAgent =
78+
'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0;Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 920)';
79+
expect(getBrowserName(userAgent)).to.eq(BrowserName.IEMOBILE);
80+
});
81+
82+
it('should recognize WebOS', () => {
83+
const userAgent =
84+
'Mozilla/5.0 (webOS/1.3; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Desktop/1.0';
85+
expect(getBrowserName(userAgent)).to.eq(BrowserName.WEBOS);
86+
});
87+
88+
it('should recognize an unlisted browser', () => {
89+
const userAgent =
90+
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Awesome/2.0.012';
91+
expect(getBrowserName(userAgent)).to.eq('Awesome');
92+
});
93+
94+
it('should default to Other', () => {
95+
const userAgent =
96+
'Mozilla/5.0 (iPhone; CPU iPhone OS 8_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12D508 [FBAN/FBIOS;FBAV/27.0.0.10.12;FBBV/8291884;FBDV/iPhone7,1;FBMD/iPhone;FBSN/iPhone OS;FBSV/8.2;FBSS/3; FBCR/vodafoneIE;FBID/phone;FBLC/en_US;FBOP/5]';
97+
expect(getBrowserName(userAgent)).to.eq(BrowserName.OTHER);
98+
});
99+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/**
19+
* Enums for Browser name.
20+
*/
21+
export enum BrowserName {
22+
ANDROID = 'Android',
23+
BLACKBERRY = 'Blackberry',
24+
EDGE = 'Edge',
25+
FIREFOX = 'Firefox',
26+
IE = 'IE',
27+
IEMOBILE = 'IEMobile',
28+
OPERA = 'Opera',
29+
OTHER = 'Other',
30+
CHROME = 'Chrome',
31+
SAFARI = 'Safari',
32+
SILK = 'Silk',
33+
WEBOS = 'Webos'
34+
}
35+
36+
/**
37+
* Determine the browser for the purposes of reporting usage to the API
38+
*/
39+
export function getBrowserName(userAgent: string): BrowserName | string {
40+
const ua = userAgent.toLowerCase();
41+
if (ua.includes('opera/') || ua.includes('opr/') || ua.includes('opios/')) {
42+
return BrowserName.OPERA;
43+
} else if (ua.includes('iemobile')) {
44+
// Windows phone IEMobile browser.
45+
return BrowserName.IEMOBILE;
46+
} else if (ua.includes('msie') || ua.includes('trident/')) {
47+
return BrowserName.IE;
48+
} else if (ua.includes('edge/')) {
49+
return BrowserName.EDGE;
50+
} else if (ua.includes('firefox/')) {
51+
return BrowserName.FIREFOX;
52+
} else if (ua.includes('silk/')) {
53+
return BrowserName.SILK;
54+
} else if (ua.includes('blackberry')) {
55+
// Blackberry browser.
56+
return BrowserName.BLACKBERRY;
57+
} else if (ua.includes('webos')) {
58+
// WebOS default browser.
59+
return BrowserName.WEBOS;
60+
} else if (
61+
ua.includes('safari/') &&
62+
!ua.includes('chrome/') &&
63+
!ua.includes('crios/') &&
64+
!ua.includes('android')
65+
) {
66+
return BrowserName.SAFARI;
67+
} else if (
68+
(ua.includes('chrome/') || ua.includes('crios/')) &&
69+
!ua.includes('edge/')
70+
) {
71+
return BrowserName.CHROME;
72+
} else if (ua.includes('android')) {
73+
// Android stock browser.
74+
return BrowserName.ANDROID;
75+
} else {
76+
// Most modern browsers have name/version at end of user agent string.
77+
const re = /([a-zA-Z\d\.]+)\/[a-zA-Z\d\.]*$/;
78+
const matches = userAgent.match(re);
79+
if (matches?.length === 2) {
80+
return matches[1];
81+
}
82+
}
83+
return BrowserName.OTHER;
84+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import { SDK_VERSION } from '@firebase/app-exp';
19+
import { expect } from 'chai';
20+
import { ClientPlatform, getClientVersion } from './version';
21+
22+
describe('getClientVersion', () => {
23+
context('browser', () => {
24+
it('should set the correct version', () => {
25+
expect(getClientVersion(ClientPlatform.BROWSER)).to.eq(
26+
`Chrome/JsCore/${SDK_VERSION}/FirebaseCore-web`
27+
);
28+
});
29+
});
30+
31+
context('worker', () => {
32+
it('should set the correct version', () => {
33+
expect(getClientVersion(ClientPlatform.WORKER)).to.eq(
34+
`Chrome-Worker/JsCore/${SDK_VERSION}/FirebaseCore-web`
35+
);
36+
});
37+
});
38+
39+
context('React Native', () => {
40+
it('should set the correct version', () => {
41+
expect(getClientVersion(ClientPlatform.REACT_NATIVE)).to.eq(
42+
`ReactNative/JsCore/${SDK_VERSION}/FirebaseCore-web`
43+
);
44+
});
45+
});
46+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import { SDK_VERSION } from '@firebase/app-exp';
19+
import { getBrowserName } from './browser';
20+
import { getUA } from '@firebase/util';
21+
22+
const CLIENT_IMPLEMENTATION = 'JsCore';
23+
24+
export enum ClientPlatform {
25+
BROWSER = 'Browser',
26+
NODE = 'Node',
27+
REACT_NATIVE = 'ReactNative',
28+
WORKER = 'Worker'
29+
}
30+
31+
enum ClientFramework {
32+
// No other framework used.
33+
DEFAULT = 'FirebaseCore-web',
34+
// Firebase Auth used with FirebaseUI-web.
35+
// TODO: Pass this in when used in conjunction with FirebaseUI
36+
FIREBASEUI = 'FirebaseUI-web'
37+
}
38+
39+
/*
40+
* Determine the SDK version string
41+
*
42+
* TODO: This should be set on the Auth object during initialization
43+
*/
44+
export function getClientVersion(clientPlatform: ClientPlatform): string {
45+
let reportedPlatform: string;
46+
switch (clientPlatform) {
47+
case ClientPlatform.BROWSER:
48+
// In a browser environment, report the browser name.
49+
reportedPlatform = getBrowserName(getUA());
50+
break;
51+
case ClientPlatform.WORKER:
52+
// Technically a worker runs from a browser but we need to differentiate a
53+
// worker from a browser.
54+
// For example: Chrome-Worker/JsCore/4.9.1/FirebaseCore-web.
55+
reportedPlatform = `${getBrowserName(getUA())}-${clientPlatform}`;
56+
break;
57+
default:
58+
reportedPlatform = clientPlatform;
59+
}
60+
return `${reportedPlatform}/${CLIENT_IMPLEMENTATION}/${SDK_VERSION}/${ClientFramework.DEFAULT}`;
61+
}

0 commit comments

Comments
 (0)