Check browser for U2F capability - javascript

Is there a way to check whether a browser supports U2F or not?
I know that right now, Chrome is the only browser that officially does U2F, but there are addons for Firefox and there may also be customized browsers which may have gotten U2F.
I don't want to ditch such browsers like Google does, because the addon users wouldn't be able to use it.
I saw that GitHub seems to have a way to see it (because it distinguished between Firefox with and without addon), but I have no idea how to do that.

Use library caniuse-support, which uses information from the service caniuse.com (https://caniuse.com/#feat=u2f) and uses library bowser (browser detector):
const {
getSupport,
currentBrowser,
} = CaniuseSupport;
const test1 = getSupport("u2f"); // current browser
console.log(
"Get feature support of U2F current browser (" +
currentBrowser.id +
" " +
currentBrowser.version +
"):",
test1.level
);
CodePen sandbox

It's 2019 now and there actually have been some interesting improvements to the entire U2F stuff.
The U2F browser API has essentially been replaced by WebAuthn, and while sure that is throwing out some older browsers, there isnt really any relevant older browser that actually supports the U2F API which is still in a lot of use as chrome auto-updates anyway and chromium and its forks are basically the only browsers that natively supported U2F out of the box.
and with the new webauthn, you have functions you can actually check for, based on what I library I use has in an example document:
if (!navigator.credentials || !navigator.credentials.create) {
//try navigator.credentials.get for login instead of create
//tell the user
}

Related

Warning IE11 users their browser is unsupported in React 18

We are in the process of upgrading our React v17 app to v18. Currently we use react-app-polyfill as well as bowser to check if users are using a supported browser, and show a simple alert if they aren't. The app doesn't work properly on IE11 but the alert at least appears.
Now that we don't have any specific requirements to support IE11 it would be nice to remove the polyfill dependency, but obviously nothing within the React app will render without it, alert included.
Aside from the hacky solution of hardcoding text into the index.html root div, does anyone have a simple way of notifying users of a) IE11 and / or b) any unsuitable browser that their browser is not supported?
You may use a <script> tag with nomodule attribute inside your index.html like this:
<script nomodule>
alert('Sorry, you need to upgrade your web browser :(');
// or
window.location.href = 'a static page where you explain what to do';
</script>
This script will only be executed on web browsers that do not support ES Modules, which are Chrome <61, Firefox <60, Safari <11, Edge <16 and all versions of Internet Explorer (to mention only the most common ones).
I'd lean toward Valentin's nomodule approach.
But if you have a reason for not requiring module support, then I'd lean toward:
Doing a feature-check on some JavaScript language feature that you know IE doesn't have but you know your target browsers will have (like class, which is supported by all modern or even semi-modern browsers and markedly predated module support in browsers; but the specific choice is up to you).
If the feature-check fails, add your alert using something other than React.
For example:
function isObsolete() {
try {
(0, eval)("class Example { }");
return false;
} catch (e) {
return true;
}
}
// ...
if (isObsolete()) {
// ...add/perform warning...
}

Web browser component javascript behaves like IE8, but in user agent says IE10

We have a SPA application which should be shown in SAP HtmlViewer Component (http://help.sap.com/erp2005_ehp_04/helpdata/en/c9/147a36c70d2354e10000009b38f839/content.htm).
According to docs the component should use the system browser, which is IE10 or on some stations IE11.
The problem is that the javascript engine behaves like the one in IE8. There are missing functions such as Array.isArray, addEventListener, Object.isExtensible etc., which leads me to believe that the brwser engine is IE8. However, when we check the user agent string it says IE10/Trident6.0, which is IE10. I am using this code to test javascript:
alert('test string.trim ' + str.trim);
alert('test Array.map ' + arr.map);
alert('test Object.isExtensible ' + Object.isExtensible );
alert('test Object.defineProperty ' + Object.defineProperty );
, and the first three are undefined.
Also, jQuery 2+ does not work (addEventListener undefiend, isArray undefined etc.), but jQuery 1 does work.
I have tried to include X-UA-Compatibility meta tag and http headers with IE=EDGE to force behavior of the newest browser (though I thing it just change document rendering and not the javascript features), but to no avail.
I also checked the registry [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION] on the computer where the SAP client is running and there is set SAPLOGON.EXE set to 0x02710 (which is IE10 according to https://msdn.microsoft.com/en-us/library/ee330730(v=vs.85).aspx).
The questions are:
are there any properties in windows system to force web browser components (which uses the system browser) to use old implementation of javascript or disallow some of the methods?
particularly in SAP, is it possible to force HtmlViewer component to behave in terms of javascript differently?
or more generally, does have anybody idea why this could be happening?
Any help will be be appreciated.

How can I detect iOS6 device using feature detection

Is there any generic way to detect iOS6 device using feature detection.
I think the best way is always to parse the user agent string but you can detect the Safari version introduced with iOS 6 using a previously unsupported feature (see this article for a more complete list, I'll provide just one example).
Basically you have to mimic the same technique used by modernizr, with this piece of code you'll check if the <input> type file is supported, if it is then you're running on Safari with iOS 6 or greater. Of course just using features you can't be sure that the user isn't using another browser (that's why I prefer the user agent string if you have to detect the OS version). For a comparison see this post here on SO.
function isNewVersion() {
var elem = document.createElement("input");
elem.setAttribute("type", "file");
return elem.type !== "text";
}
You could check the FileReader API, but of course this'll match many modern desktop browsers, too (I'm not sure if that's going to cause you some problems, but I doubt it):
var iOS6 = false;
if(window.FileReader)
{
iOS6 = true;
}

browser identification

I want to identify if the broswer is IE then goto if block, other browser to else block in Java script.
I have one code here,
var browserName=navigator.appName;
if(browserName == "Microsoft Internet Explorer"){
IE code
}
else{
Other code
}
but i want to know is there any other way of implementing it?
Rather than do browser sniffing, you should do feature detection. Later versions of IE may support standards compliant stuff that in older versions you needed to work around or use MS-specific stuff.
Microsoft themselves have written up about the best way to do this and provide examples of both bad code (via sniffing) and good code (via detection). Make sure you go down the "good code" route.
I just started using this script to identify browser, version, and OS:
http://www.quirksmode.org/js/detect.html
If you are needing to use different code based on browser support for certain objects or methods, it's usually better to use object or method detection instead of browser detection. I use the browser detection for collecting statistics on my users, not for enabling or disabling features.
Quirksmode has a short article about why you don't use browser detection this way: http://www.quirksmode.org/js/support.html It's also linked from the browser detection script.
I found that This task is quite difficult as browsers all have similar names and different userAgent strings, so this is my Conditional statement to identify browsers.
I used this to identify the browser for different style sheets.
function styc()
{
var str = navigator.userAgent;
var res = navigator.userAgent.match(/Trident/);
var res2 = navigator.userAgent.match(/Firefox/);
if(res=="Trident"||res2=="Firefox")
{
//alert(navigator.userAgent);//for testing
document.getElementById('IE_fix').setAttribute("href", "IE_fix.css");
}
else
{
//alert("no");//for testing
document.getElementById('IE_fix').setAttribute("href", "mt_default.css");
}
}
Find a unique word in the userAgent string match it and check if the condition is true or not true depending on what you are doing.
The unique word I found for IE is Trident, and also identifies IE versions according to MicroSoft(not positive on this).

Which is a better way to detect a client's user-agent?

I am interested if which would be the best place to detect the client's user-agent, client-side (javascript) or server-side? I brought up the question due to the fact that some IE8 users are getting a message saying they're using IE6.
The short and correct answer is : do not use anything that relies on UserAgent sniffing.
To reliable be able to adjust code paths you should test for the specific 'thing' that the codepath is adjusted for, primarily features. This is called Feature Detection.
So if feature X is supported we do this, if not we do that.
Deducing if a feature is supported based on which UserAgent is present will rapidly fail, especially when new browsers come to the marked.
Take the following example, which can actually be found in several major libraries (!)
if (isIE8) {
// use new feature provided by IE8
} else if (isIE7) {
// use not so new feature provided by IE7 (and IE8)
} else {
// use fallback for all others (which also works in IE7 and IE8)
}
What do you think happens when IE9 comes along?
The correct pattern in this case would be
if ("addEventListener" in foo) {
// use DOM level 2 addEventListener to attach events
foo.addEventListener(...
} else if ("attachEvent" in foo) {
// use IE's proprietary attachEvent method
foo.attachEvent(...
} else {
// fall back to DOM 0
foo["on" + eventName] = ....
}
The User-agent available on both sides should be the same, unless there's funny stuff going on, which normally isn't.
If you want to show a message to IE6 users, I suggest you use conditional comments. They're an IE-specific feature and work very well for detecting IE versions.
The information found through client or server-side detection is basically the same.
Keep in mind it is extremely easy to spoof what browser you're in. There is no fail-safe way to detect all browser types accurately.
i don't know how you're checking for the user agent, but i'd do this way:
<%=
case request.env['HTTP_USER_AGENT']
when /Safari/
"it's a Mac!"
when /iPhone/
"it's a iPhone"
else
"i don't know :("
end
%>
checking directly in the user request seems to be the most consistent way to verify the user browser. And the request.env is avaliable in your controller and views, so you could pass this to rjs if needed.
For those who need to get the actual user-agent using JavaScript, you can use navigator.userAgent

Categories

Resources