mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-26 10:27:32 +09:00
110 lines
3.3 KiB
JavaScript
110 lines
3.3 KiB
JavaScript
(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: function() {
|
|
return fetch('https://example.com/.well-known/idp-proxy/idp.sjs?' + this.id)
|
|
.then(response => response.status === 200);
|
|
},
|
|
checkLogin: function(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: function(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: function(usernameHint) {
|
|
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: function(payload, origin, usernameHint) {
|
|
dump('idp: generateAssertion(' + payload + ')\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(usernameHint),
|
|
contents: payload
|
|
})
|
|
});
|
|
},
|
|
|
|
validateAssertion: function(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));
|