Skip to content

Instantly share code, notes, and snippets.

@andreban
Last active October 13, 2021 05:57
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save andreban/550f34ed19cc3d7f51d0f95bd246a1a6 to your computer and use it in GitHub Desktop.
Save andreban/550f34ed19cc3d7f51d0f95bd246a1a6 to your computer and use it in GitHub Desktop.
/*
* Copyright 2020 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const TWA_PROTOCOL = 'android-app:';
const KEY_IS_TWA = 'isTrustedWebActivity';
/**
* This method should run on every page load. `packageName` corresponds to the ID
* of the app on the Play Store. This is important to differentiate from the page
* being opened from a Custom Tab, for instance.
*/
export function isTrustedWebActivity(packageName) {
const sessionStorageStatus = sessionStorage.getItem(KEY_IS_TWA);
if (sessionStorageStatus === 'true') {
return true;
}
const referrer = document.referrer.trim();
if (referrer.length === 0) {
return false;
}
const referrerUrl = new URL(referrer);
if (referrerUrl.protocol === TWA_PROTOCOL
&& referrerUrl.hostname === packageName) {
sessionStorage.setItem(KEY_IS_TWA, 'true');
return true;
}
return false;
}
@elgreg
Copy link

elgreg commented May 24, 2021

I tried using this, but the hostname is returning an empty string. I believe this is because the android-app protocol is not one of those listed in https://url.spec.whatwg.org/#origin (ftp, http, https, ws, wss, file) and so it's considered an opaque URL. (I freely admit to not being great at reading specs). Since there's just a protocol and path changing to look for the packageName with a '/' as the first part of pathname will fix it, so I'm testing for

&& referrerUrl.pathname.indexOf(`//${packageName}/`) === 0

Even stranger, at least in node v12, the .hostname check does work on the server for the android-app: protocol, but does not work in Chrome or Firefox. So, sadly, the final implementation of the referrer check looks like this so that it passes mocha tests 😭

  if (
    referrerUrl.protocol === TWA_PROTOCOL &&
    (referrerUrl.hostname === packageName ||
      referrerUrl.pathname.indexOf(`//${packageName}`) === 0)
  ) {
    sessionStorage.setItem(KEY_IS_TWA, "true");
    return true;
  }

I'm kind of hoping that I just missed something...

chrome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment