1

It seems like the old detection methods which have worked for iOS 11 and respective Safari version(s) do not work anymore.
I have tried this script: https://gist.github.com/cou929/7973956
But it doesn't work for safari on iOS 12 and also doesn't work for Chrome 69 on iOS 12.

This quite new library is also not working for iOS 12 browsers:
https://github.com/Maykonn/js-detect-incognito-private-browsing-paywall

So is there any solution for iOS 12 browsers yet?

BostonGlobe seems to have a solution, but I have no idea how they did it:
https://www.bostonglobe.com/sports/redsox/2018/10/09/redsox/D66J59viZ1qxyZlhI18l8L/story.html (If you want to read an BostonGlobe.com article in incognito / private mode you get a screen which asks you to log in)

low_rents
  • 4,481
  • 3
  • 27
  • 55
  • `If you want to read an BostonGlobe.com article in incognito / private mode you get a screen which asks you to log in` , when you open a site that needs you to login , in incognito , you will have to login again , that's not necessarily an indication that the site uses `incognito detection` – Alexander Solonik Oct 11 '18 at 11:47
  • 1
    @AlexanderSolonik just try it. if you are not in incognito mode - you can read the article; in incognito mode you are asked to log in and it even tells you that it detected that your browser is in incognito mode – low_rents Oct 11 '18 at 11:51

2 Answers2

2

Chrome Devtools => The module to detect incognito/private mode is called "detect-private-browsing" located at webpack:///./~/detect-private-browsing/index.js

// ./~/detect-private-browsing/index.js

function retry(isDone, next) {
    var current_trial = 0, max_retry = 50, interval = 10, is_timeout = false;
    var id = window.setInterval(
        function() {
            if (isDone()) {
                window.clearInterval(id);
                next(is_timeout);
            }
            if (current_trial++ > max_retry) {
                window.clearInterval(id);
                is_timeout = true;
                next(is_timeout);
            }
        },
        10
    );
}

function isIE10OrLater(user_agent) {
    var ua = user_agent.toLowerCase();
    if (ua.indexOf('msie') === 0 && ua.indexOf('trident') === 0) {
        return false;
    }
    var match = /(?:msie|rv:)\s?([\d\.]+)/.exec(ua);
    if (match && parseInt(match[1], 10) >= 10) {
        return true;
    }
    // MS Edge Detection from this gist: https://gist.github.com/cou929/7973956
    var edge = /edge/.exec(ua); 
    if (edge && edge[0] == "edge") { 
        return true; 
    }
    return false;
}

module.exports = {
    detectPrivateMode: function(callback) {
        var is_private;

        if (window.webkitRequestFileSystem) {
            window.webkitRequestFileSystem(
                window.TEMPORARY, 1,
                function() {
                    is_private = false;
                },
                function(e) {
                    console.log(e);
                    is_private = true;
                }
            );
        } else if (window.indexedDB && /Firefox/.test(window.navigator.userAgent)) {
            var db;
            try {
                db = window.indexedDB.open('test');
            } catch(e) {
                is_private = true;
            }

            if (typeof is_private === 'undefined') {
                retry(
                    function isDone() {
                        return db.readyState === 'done' ? true : false;
                    },
                    function next(is_timeout) {
                        if (!is_timeout) {
                            is_private = db.result ? false : true;
                        }
                    }
                );
            }
        } else if (isIE10OrLater(window.navigator.userAgent)) {
            is_private = false;
            try {
                if (!window.indexedDB) {
                    is_private = true;
                }                 
            } catch (e) {
                is_private = true;
            }
        } else if (window.localStorage && /Safari/.test(window.navigator.userAgent)) {

            // One-off check for weird sports 2.0 polyfill
            // This also impacts iOS Firefox and Chrome (newer versions), apparently
            // @see bglobe-js/containers/App.js:116
            if (window.safariIncognito) {
                is_private = true;
            } else {
                        try {
                           window.openDatabase(null, null, null, null);
                        } catch (e) {
                           is_private = true;
                        }

                try {
                    window.localStorage.setItem('test', 1);
                } catch(e) {
                    is_private = true;
                }
            } 

            if (typeof is_private === 'undefined') {
                is_private = false;
                window.localStorage.removeItem('test');
            }
        }



        retry(
            function isDone() {
                return typeof is_private !== 'undefined' ? true : false;
            },
            function next(is_timeout) {
                callback(is_private);
            }
        );
    }
};
nathan
  • 9,329
  • 4
  • 37
  • 51
  • no, sorry - I don't get it. it's a `webpack://` link? where did you get this from? – low_rents Oct 12 '18 at 10:10
  • Yes. From Chrome’s DevTools while debugging the site since it uses webpack for bundling. – nathan Oct 12 '18 at 12:21
  • wow, that's it. it's working! i just changed it to native javascript by removing the `module.exports = {}` wrapper and making `detectPrivateMode` a normal function. The only thing is - I can't still find this code via my Chrome DevTools - can you explain how exactly you found it? thank you so much! – low_rents Oct 12 '18 at 13:11
  • It's funny that BostonGlobe seems to use a modification of the one script I mentioned in my question: https://gist.github.com/cou929/7973956 – low_rents Oct 12 '18 at 13:14
  • ok, just found out how to search for a file in DevTools > Sources > Page: use the shortcut Ctrl + P (https://stackoverflow.com/a/42024808/3391783) – low_rents Oct 12 '18 at 13:29
1
//FOR IOS 12
var e = false;
if (window.localStorage && /Safari/.test(window.navigator.userAgent)) {
  if (window.safariIncognito) {
    e = true;
  } else {
    try {
      window.openDatabase(null, null, null, null);
      window.localStorage.setItem("test", 1)
    } catch (t) {
      e = true;
      alert("PRIVATE");
    }
  }
  void !e && (e = !1, window.localStorage.removeItem("test"))
}
Aryeh Beitz
  • 1,974
  • 1
  • 22
  • 23