|
1 (function(global) { |
|
2 "use strict"; |
|
3 |
|
4 function IDPJS() { |
|
5 this.domain = window.location.host; |
|
6 var p = window.location.pathname; |
|
7 this.protocol = p.substring(p.lastIndexOf('/') + 1) + window.location.hash; |
|
8 this.username = "someone@" + this.domain; |
|
9 // so rather than create a million different IdP configurations and litter |
|
10 // the world with files all containing near-identical code, let's use the |
|
11 // hash/URL fragment as a way of generating instructions for the IdP |
|
12 this.instructions = window.location.hash.replace("#", "").split(":"); |
|
13 this.port = window.rtcwebIdentityPort; |
|
14 this.port.onmessage = this.receiveMessage.bind(this); |
|
15 this.sendResponse({ |
|
16 type : "READY" |
|
17 }); |
|
18 } |
|
19 |
|
20 IDPJS.prototype.getDelay = function() { |
|
21 // instructions in the form "delay123" have that many milliseconds |
|
22 // added before sending the response |
|
23 var delay = 0; |
|
24 function addDelay(instruction) { |
|
25 var m = instruction.match(/^delay(\d+)$/); |
|
26 if (m) { |
|
27 delay += parseInt(m[1], 10); |
|
28 } |
|
29 } |
|
30 this.instructions.forEach(addDelay); |
|
31 return delay; |
|
32 }; |
|
33 |
|
34 function is(target) { |
|
35 return function(instruction) { |
|
36 return instruction === target; |
|
37 }; |
|
38 } |
|
39 |
|
40 IDPJS.prototype.sendResponse = function(response) { |
|
41 // we don't touch the READY message unless told to |
|
42 if (response.type === "READY" && !this.instructions.some(is("ready"))) { |
|
43 this.port.postMessage(response); |
|
44 return; |
|
45 } |
|
46 |
|
47 // if any instruction is "error", return an error. |
|
48 if (this.instructions.some(is("error"))) { |
|
49 response.type = "ERROR"; |
|
50 } |
|
51 |
|
52 window.setTimeout(function() { |
|
53 this.port.postMessage(response); |
|
54 }.bind(this), this.getDelay()); |
|
55 }; |
|
56 |
|
57 IDPJS.prototype.receiveMessage = function(ev) { |
|
58 var message = ev.data; |
|
59 switch (message.type) { |
|
60 case "SIGN": |
|
61 if (message.username) { |
|
62 var at = message.username.indexOf("@"); |
|
63 if (at < 0) { |
|
64 this.username = message.username + "@" + this.domain; |
|
65 } else if (message.username.substring(at + 1) === this.domain) { |
|
66 this.username = message.username; |
|
67 } |
|
68 } |
|
69 this.sendResponse({ |
|
70 type : "SUCCESS", |
|
71 id : message.id, |
|
72 message : { |
|
73 idp : { |
|
74 domain : this.domain, |
|
75 protocol : this.protocol |
|
76 }, |
|
77 assertion : JSON.stringify({ |
|
78 username : this.username, |
|
79 contents : message.message |
|
80 }) |
|
81 } |
|
82 }); |
|
83 break; |
|
84 |
|
85 case "VERIFY": |
|
86 var payload = JSON.parse(message.message); |
|
87 var contents = payload.contents; |
|
88 if (this.instructions.some(is("bad"))) { |
|
89 contents = {}; |
|
90 } |
|
91 this.sendResponse({ |
|
92 type : "SUCCESS", |
|
93 id : message.id, |
|
94 message : { |
|
95 identity : payload.username, |
|
96 contents : contents |
|
97 } |
|
98 }); |
|
99 break; |
|
100 |
|
101 default: |
|
102 this.sendResponse({ |
|
103 type : "ERROR", |
|
104 id : message.id, |
|
105 error : JSON.stringify(message) |
|
106 }); |
|
107 break; |
|
108 } |
|
109 }; |
|
110 |
|
111 global.idp = new IDPJS(); |
|
112 }(this)); |