tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

idp.js (3486B)


      1 (function (global) {
      2  "use strict";
      3 
      4  // rather than create a million different IdP configurations and litter the
      5  // world with files all containing near-identical code, let's use the hash/URL
      6  // fragment as a way of generating instructions for the IdP
      7  var instructions = global.location.hash.replace("#", "").split(":");
      8  function is(target) {
      9    return function (instruction) {
     10      return instruction === target;
     11    };
     12  }
     13 
     14  function IDPJS() {
     15    this.domain = global.location.host;
     16    var path = global.location.pathname;
     17    this.protocol =
     18      path.substring(path.lastIndexOf("/") + 1) + global.location.hash;
     19    this.id = crypto.getRandomValues(new Uint8Array(10)).join(".");
     20  }
     21 
     22  IDPJS.prototype = {
     23    getLogin() {
     24      return fetch(
     25        "https://example.com/.well-known/idp-proxy/idp.sjs?" + this.id
     26      ).then(response => response.status === 200);
     27    },
     28    checkLogin(result) {
     29      return this.getLogin().then(loggedIn => {
     30        if (loggedIn) {
     31          return result;
     32        }
     33        return Promise.reject({
     34          name: "IdpLoginError",
     35          loginUrl:
     36            "https://example.com/.well-known/idp-proxy/login.html#" + this.id,
     37        });
     38      });
     39    },
     40 
     41    borkResult(result) {
     42      if (instructions.some(is("throw"))) {
     43        throw new Error("Throwing!");
     44      }
     45      if (instructions.some(is("fail"))) {
     46        return Promise.reject(new Error("Failing!"));
     47      }
     48      if (instructions.some(is("login"))) {
     49        return this.checkLogin(result);
     50      }
     51      if (instructions.some(is("hang"))) {
     52        return new Promise(r => {});
     53      }
     54      dump("idp: result=" + JSON.stringify(result) + "\n");
     55      return Promise.resolve(result);
     56    },
     57 
     58    _selectUsername(usernameHint) {
     59      dump("_selectUsername: usernameHint(" + usernameHint + ")\n");
     60      var username = "someone@" + this.domain;
     61      if (usernameHint) {
     62        var at = usernameHint.indexOf("@");
     63        if (at < 0) {
     64          username = usernameHint + "@" + this.domain;
     65        } else if (usernameHint.substring(at + 1) === this.domain) {
     66          username = usernameHint;
     67        }
     68      }
     69      return username;
     70    },
     71 
     72    generateAssertion(payload, origin, options) {
     73      dump(
     74        "idp: generateAssertion(" +
     75          payload +
     76          ", " +
     77          origin +
     78          ", " +
     79          JSON.stringify(options) +
     80          ")\n"
     81      );
     82      var idpDetails = {
     83        domain: this.domain,
     84        protocol: this.protocol,
     85      };
     86      if (instructions.some(is("bad-assert"))) {
     87        idpDetails = {};
     88      }
     89      return this.borkResult({
     90        idp: idpDetails,
     91        assertion: JSON.stringify({
     92          username: this._selectUsername(options.usernameHint),
     93          contents: payload,
     94        }),
     95      });
     96    },
     97 
     98    validateAssertion(assertion, origin) {
     99      dump("idp: validateAssertion(" + assertion + ")\n");
    100      var assertion = JSON.parse(assertion);
    101      if (instructions.some(is("bad-validate"))) {
    102        assertion.contents = {};
    103      }
    104      return this.borkResult({
    105        identity: assertion.username,
    106        contents: assertion.contents,
    107      });
    108    },
    109  };
    110 
    111  if (!instructions.some(is("not_ready"))) {
    112    dump("registering idp.js" + global.location.hash + "\n");
    113    var idp = new IDPJS();
    114    global.rtcIdentityProvider.register({
    115      generateAssertion: idp.generateAssertion.bind(idp),
    116      validateAssertion: idp.validateAssertion.bind(idp),
    117    });
    118  }
    119 })(this);