(
function (global) {
"use strict";
// rather than create a million different IdP configurations and litter the
// world with files all containing near-identical code, let's use the hash/URL
// fragment as a way of generating instructions for the IdP
var instructions = global.location.hash.replace(
"#",
"").split(
":");
function is(target) {
return function (instruction) {
return instruction === target;
};
}
function IDPJS() {
this.domain = global.location.host;
var path = global.location.pathname;
this.protocol =
path.substring(path.lastIndexOf(
"/") + 1) + global.location.hash;
this.id = crypto.getRandomValues(
new Uint8Array(10)).join(
".");
}
IDPJS.prototype = {
getLogin() {
return fetch(
"https://example.com/.well-known/idp-proxy/idp.sjs?" + this.id
).then(response => response.status === 200);
},
checkLogin(result) {
return this.getLogin().then(loggedIn => {
if (loggedIn) {
return result;
}
return Promise.reject({
name:
"IdpLoginError",
loginUrl:
"https://example.com/.well-known/idp-proxy/login.html#" + this.id,
});
});
},
borkResult(result) {
if (instructions.some(is(
"throw"))) {
throw new Error(
"Throwing!");
}
if (instructions.some(is(
"fail"))) {
return Promise.reject(
new Error(
"Failing!"));
}
if (instructions.some(is(
"login"))) {
return this.checkLogin(result);
}
if (instructions.some(is(
"hang"))) {
return new Promise(r => {});
}
dump(
"idp: result=" + JSON.stringify(result) +
"\n");
return Promise.resolve(result);
},
_selectUsername(usernameHint) {
dump(
"_selectUsername: usernameHint(" + usernameHint +
")\n");
var username =
"someone@" +
this.domain;
if (usernameHint) {
var at = usernameHint.indexOf(
"@");
if (at < 0) {
username = usernameHint +
"@" +
this.domain;
}
else if (usernameHint.substring(at + 1) ===
this.domain) {
username = usernameHint;
}
}
return username;
},
generateAssertion(payload, origin, options) {
dump(
"idp: generateAssertion(" +
payload +
", " +
origin +
", " +
JSON.stringify(options) +
")\n"
);
var idpDetails = {
domain:
this.domain,
protocol:
this.protocol,
};
if (instructions.some(is(
"bad-assert"))) {
idpDetails = {};
}
return this.borkResult({
idp: idpDetails,
assertion: JSON.stringify({
username:
this._selectUsername(options.usernameHint),
contents: payload,
}),
});
},
validateAssertion(assertion, origin) {
dump(
"idp: validateAssertion(" + assertion +
")\n");
var assertion = JSON.parse(assertion);
if (instructions.some(is(
"bad-validate"))) {
assertion.contents = {};
}
return this.borkResult({
identity: assertion.username,
contents: assertion.contents,
});
},
};
if (!instructions.some(is(
"not_ready"))) {
dump(
"registering idp.js" + global.location.hash +
"\n");
var idp =
new IDPJS();
global.rtcIdentityProvider.register({
generateAssertion: idp.generateAssertion.bind(idp),
validateAssertion: idp.validateAssertion.bind(idp),
});
}
})(
this);