Skip to content

Commit

Permalink
Merge pull request #24 from overhide/oh-social_support
Browse files Browse the repository at this point in the history
Support overhide-social for Microsoft and Google.
  • Loading branch information
JakubNer authored May 15, 2021
2 parents 77813c1 + 052dd5f commit 5c4e881
Show file tree
Hide file tree
Showing 11 changed files with 247 additions and 26 deletions.
2 changes: 1 addition & 1 deletion dist/ledgers.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/ledgers.js.map

Large diffs are not rendered by default.

23 changes: 22 additions & 1 deletion docs/ledgers.js-rendered-docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,11 @@ <h3>IMPARTERS</h3>
<ul>
<li>ohledger</li>
<li>ohledger-web3</li>
<li>ohledger-social</li>
</ul>
<p>The <em>ohledger-social</em> imparter is to use the <em>overhide-ledger</em> with credentials stored online behind a Microsoft or
Google social login. The <em>overhide-ledger</em> credentials are not transferred to the client. They sit in the cloud and
are used once a social provider allows it.</p>
<p>Thus far Bitcoin is only supported in manual mode (no Bitcoin wallet injection into target site):</p>
<ul>
<li>btc-manual</li>
Expand Down Expand Up @@ -418,7 +422,7 @@ <h4>eth-web3</h4>
</blockquote>
<p>The denomination for amounts is the Wei</p>
</blockquote>
<h4>ohledger, ohledger-web3</h4>
<h4>ohledger, ohledger-web3, ohledger-social</h4>
<blockquote>
<p>Addresses and secret keys use Ethereum format.</p>
<p>Addresses are 20 bytes: 42 character 'hex' strings prefixed with '0x'.</p>
Expand Down Expand Up @@ -724,6 +728,10 @@ <h3 class='fl m0' id='eventoncredentialsupdate'>
<td><code>{imparterTag:..,address:..}</code></td>
</tr>
<tr>
<td>ohledger-social</td>
<td><code>{imparterTag:..,address:..}</code></td>
</tr>
<tr>
<td>btc-manual</td>
<td><code>{imparterTag:..,address:..}</code></td>
</tr>
Expand Down Expand Up @@ -1397,6 +1405,11 @@ <h3 class='fl m0' id='setcredentials'>
<td>not supported</td>
</tr>
<tr>
<td>ohledger-social</td>
<td><code>{provider:..}</code></td>
<td><code>provider</code> is one of 'google' or 'microsoft'; if null, log-out</td>
</tr>
<tr>
<td>btc-manual</td>
<td><code>{address:..}</code></td>
<td></td>
Expand Down Expand Up @@ -1698,6 +1711,10 @@ <h3 class='fl m0' id='getcredentials'>
<td><code>{address:..}</code></td>
</tr>
<tr>
<td>ohledger-social</td>
<td><code>{address:..}</code></td>
</tr>
<tr>
<td>btc-manual</td>
<td><code>{address:..}</code></td>
</tr>
Expand Down Expand Up @@ -2503,6 +2520,10 @@ <h3 class='fl m0' id='createtransaction'>
<td>{message:.., signature:..}</td>
</tr>
<tr>
<td>ohledger-social</td>
<td>{message:.., signature:..}</td>
</tr>
<tr>
<td>btc-manual</td>
<td>null</td>
</tr>
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ledgers.js",
"version": "4.3.0",
"version": "4.4.0",
"description": "JavaScript library for ledger-based authorizations :: abstracting different ledgers to be used in an application's authentication and authorization workflows.",
"engines": {
"node": ">=10.13.0"
Expand Down Expand Up @@ -51,6 +51,6 @@
"pack-prod": "webpack --mode=production",
"all": "npm run docs & npm run pack-prod",
"watch": "watch \"npm run pack-dev\" ./src",
"play": "http-server ./"
"play": "http-server -c-1 ./"
}
}
7 changes: 4 additions & 3 deletions play/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
<p>Invalid <em>imparterTag</em>.</p>
</div>
<div id="ohledgernote" class="w3-panel w3-yellow">
<p>For <em>ohledger</em> and <em>ohledger-web3</em> imparters please first <a href="https://test.ledger.overhide.io/onboard" target="_blank">register a provider address</a> with the <em>overhide-ledger</em> test network.</p>
<p>For <em>ohledger</em>, <em>ohledger-web3</em>, and <em>ohledger-social</em> imparters please first <a href="https://test.ledger.overhide.io/onboard" target="_blank">register a provider address</a> with the <em>overhide-ledger</em> test network.</p>
</div>
<div id="ethnote" class="w3-panel w3-yellow">
<p>For the <em>eth-web3</em> imparter please use addresses from the <em>Rinkeby</em> testnet.</p>
Expand Down Expand Up @@ -267,9 +267,9 @@
$("#invalidnote").hide();
$("[name='imparterTag']").change(() => {
data.imparterTag = data.imparterTag.trim();
/^ohledger(-web3)?$/.test(data.imparterTag) ? $("#ohledgernote").show() : $("#ohledgernote").hide();
/^ohledger(-web3|-social)?$/.test(data.imparterTag) ? $("#ohledgernote").show() : $("#ohledgernote").hide();
/^eth-web3$/.test(data.imparterTag) ? $("#ethnote").show() : $("#ethnote").hide();
/^(ohledger(-web3)?|eth-web3|btc-manual)?$/.test(data.imparterTag) ? $("#invalidnote").hide() : $("#invalidnote").show();
/^(ohledger(-web3|-social)?|eth-web3|btc-manual)?$/.test(data.imparterTag) ? $("#invalidnote").hide() : $("#invalidnote").show();
})

/* =========================================================================
Expand All @@ -283,6 +283,7 @@
el.append(new Option('btc-manual','btc-manual'));
el.append(new Option('ohledger-web3','ohledger-web3'));
el.append(new Option('ohledger','ohledger'));
el.append(new Option('ohledger-social','ohledger-social'));
}
}

Expand Down
19 changes: 12 additions & 7 deletions src/fns/dom_fns.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ class dom_fns {
reject = null;

constructor() {
window.document.addEventListener('oh$-popup-close', (e) => {
this.makePopupHidden('user close', true);
window.addEventListener('message', (e) => {
if (!e.data || !e.data.event) return;
switch(e.data.event) {
case 'oh$-popup-close':
this.makePopupHidden('user close', true);
break;
}
});
}

Expand All @@ -19,23 +24,23 @@ class dom_fns {
// @param {string} triggerFor
// @param {Object} data - to stringify and sent as event.details.
raiseEventClick(imparterTag, triggerFor) {
window.parent.document.dispatchEvent(new CustomEvent('oh$-event', {detail: JSON.stringify({
window.parent.postMessage({event: 'oh$-event', detail: JSON.stringify({
imparterTag: imparterTag,
triggerFor: triggerFor,
click: true
})}));
})});
}

// raise oh$-event
// @param {string} imparterTag
// @param {string} triggerFor
// @param {Object} data - to stringify and sent as event.details.
raiseEvent(imparterTag, triggerFor, data) {
window.parent.document.dispatchEvent(new CustomEvent('oh$-event', {detail: JSON.stringify({
window.parent.postMessage({event: 'oh$-event', detail: JSON.stringify({
...data,
imparterTag: imparterTag,
triggerFor: triggerFor
})}));
})});
}

// promise used for popups and resolutions via oh-ledger-* messages.
Expand Down Expand Up @@ -85,7 +90,7 @@ class dom_fns {
popup.style.display='none';
popup.innerHTML = `
<div id="oh-popup-container-div">
<a href="#" title="Close" id="oh-popup-close" onclick="window.parent.document.dispatchEvent(new CustomEvent('oh$-popup-close',{})); return false;">X</a>
<a href="#" title="Close" id="oh-popup-close" onclick="window.parent.postMessage({event: 'oh$-popup-close'}); return false;">X</a>
<iframe id="oh-ledger-iframe"></iframe>
</div>
`;
Expand Down
2 changes: 1 addition & 1 deletion src/frames/btc_manual_createTransaction.html
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@
}

function ok() {
window.parent.document.dispatchEvent(new CustomEvent('oh$-popup-close',{detail:'ok'}));
window.parent.postMessage({event: 'oh$-popup-close'}, '*');
}
</script>
</html>
4 changes: 2 additions & 2 deletions src/frames/btc_manual_sign.html
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@


function cancel() {
window.parent.document.dispatchEvent(new CustomEvent('oh$-popup-close',{detail:'cancel'}));
window.parent.postMessage({event: 'oh$-popup-close'}, '*');
}

function submit() {
Expand All @@ -177,7 +177,7 @@
})
}).then((result) => {
if (result.status == 200) {
window.parent.document.dispatchEvent(new CustomEvent('oh$-popup-signature',{detail: {signature:btoa(data.signature)}}));
window.parent.postMessage({event: 'oh$-popup-signature', detail: {signature:btoa(data.signature)}}, '*');
} else {
data.toast = "Invalid signature.";
fillValues();
Expand Down
16 changes: 11 additions & 5 deletions src/imparters/btc-manual.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class btc_manual {
'test':'https://test.bitcoin.overhide.io'
};

url = 'http://localhost:8080/src/frames';
url = 'https://overhide.github.io/ledgers.js/src/frames';
address = null;
mode = 'test';

Expand All @@ -18,11 +18,17 @@ class btc_manual {
this.__fetch = __fetch;
this.fire = fire;

window.document.addEventListener('oh$-popup-signature', (e) => {
if ('detail' in e && e.detail && 'signature' in e.detail) {
this.domFns.makePopupHidden(e.detail.signature, false);
window.addEventListener('message', (e) => {
if (!e.data || !e.data.event) return;
switch(e.data.event) {
case 'oh$-popup-signature':
if ('detail' in e.data && e.data.detail && 'signature' in e.data.detail) {
this.domFns.makePopupHidden(e.data.detail.signature, false);
} else {
this.domFns.makePopupHidden(`no signature`, true);
}
break;
}
this.domFns.makePopupHidden(`no signature`, true);
});
}

Expand Down
170 changes: 170 additions & 0 deletions src/imparters/ohledger-social.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import ohledger_fns from '../fns/ohledger_fns.js';
import imparter_fns from '../fns/imparter_fns.js';

class ohledger_social {
static tag = 'ohledger-social';

address = null;
mode = 'test';
social = null;

constructor(domFns, overhide_wallet, web3_wallet, getToken, __fetch, fire) {
this.domFns = domFns;
this.overhide_wallet = overhide_wallet;
this.eth_accounts = web3_wallet.eth_accounts;
this.getToken = getToken;
this.__fetch = __fetch;
this.fire = fire;

window.addEventListener('message', (e) => {
if (!e.data || !e.data.event) return;
switch(e.data.event) {
case 'oh$-login-success':
this.domFns.makePopupHidden('login success', false);
break;
case 'oh$-login-failed':
this.domFns.makePopupHidden('login failure', true);
break;
case 'oh$-logout-success':
this.domFns.makePopupHidden('logout', false);
break;
}
});
}

canSetCredentials() {
return true;
}

canGenerateCredentials() {
return false;
}

canChangeNetwork() {
return true;
}

async setCredentials(credentials) {
if (!credentials) {
if (!this.social) throw new Error("Not logged in");
this.domFns.hideAllPopupContents();
this.domFns.setFrame(`https://overhide.b2clogin.com/overhide.onmicrosoft.com/B2C_1_${this.social}/oauth2/v2.0/logout?redirect_uri=http%3A%2F%2Fsocial.overhide.io%2Flogout`);
await this.domFns.makePopupVisible();
this.address = null;
} else if ('provider' in credentials) {
this.social = credentials.provider;
await this.sign(`setting credentials on ${new Date()}`);
} else {
throw new Error("Incorrect credentials options.");
}
this.fire('onCredentialsUpdate', { imparterTag: ohledger_social.tag, address: this.address });
return true;
}

getCredentials() {
return {"address":this.address};
}

generateCredentials(options) {
return false;
}

setNetwork(details) {
ohledger_fns.setNetwork_check_details(details);

this.mode = details.mode;
this.fire('onNetworkChange', { imparterTag: ohledger_social.tag, currency: 'USD', mode: details.mode, uri: this.overhide_wallet.remuneration_uri[details.mode]});
return true;
}

getNetwork() {
return { "currency": "USD", "mode": this.mode, "uri": this.overhide_wallet.remuneration_uri[this.mode]};
}

getOverhideRemunerationAPIUri() {
if (!this.mode) throw new Error("network 'mode' must be set, use setNetwork");
return this.overhide_wallet.remuneration_uri[this.mode];
}

async getFromDollars(dollarAmount) {
return dollarAmount * 100;
}

async getTxs(recipient, date, tallyOnly, tallyDollars) {
imparter_fns.getTxs_check_details(recipient, date);

const to = recipient.address;
const uri = this.getOverhideRemunerationAPIUri();

if (!this.mode) throw new Error("network 'mode' must be set, use setNetwork");
if (!this.address) throw new Error("from 'address' not set: use setCredentials");
const from = this.address;

return await imparter_fns.getTxs_retrieve(uri, from, to, tallyOnly, tallyDollars, date, this.getToken(), this.__fetch);
}

async isOnLedger() {
const uri = this.getOverhideRemunerationAPIUri();
if (!this.mode) throw new Error("network 'mode' must be set, use setNetwork");
if (!this.address) throw new Error("from 'address' not set: use setCredentials");
const from = this.address;
if (!uri) throw new Error('no uri for request, unsupported network selected in wallet?');
const message = 'verify ownership of address by signing';
const signature = await this.sign(message);

return await imparter_fns.isSignatureValid_call(uri, signature, message, from, this.getToken(), this.__fetch);
}

async sign(message) {
try {
const res = this.eth_accounts.create();
const karnet = res.privateKey;
this.domFns.hideAllPopupContents();
this.domFns.setFrame(`https://social.overhide.io/pending`, 30, 10);
const popupPromise = this.domFns.makePopupVisible();
window.open(
`https://overhide.b2clogin.com/overhide.onmicrosoft.com/B2C_1_${this.social}/oauth2/v2.0/authorize?client_id=aa71ffc7-2884-4045-898f-7db3a177c1a1&response_type=code&redirect_uri=https%3A%2F%2Fsocial.overhide.io%2Fredirect/${this.social}&response_mode=query&scope=aa71ffc7-2884-4045-898f-7db3a177c1a1&state=${karnet}`,
'_blank',
{height: 300, width: 300}
);
await popupPromise;
return await this.__fetch(`https://social.overhide.io/sign?karnet=${karnet}&message=${btoa(message)}`, {
method: "GET",
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Authorization': `Bearer ${this.getToken()}`
}})
.then(async (result) => {
if (result.status == 200) {
const resultValue = await result.json();
this.address = resultValue.address;
return atob(resultValue.signature);
} else {
throw new Error(await result.text());
}
});
} catch(e) {
throw String(e)
}
}

async createTransaction(amount, to, options) {
if (!this.mode) throw new Error("network 'mode' must be set, use setNetwork");
if (!this.address) throw new Error("from 'address' not set: use setCredentials");
const from = this.address;
const uri = this.getOverhideRemunerationAPIUri();

await ohledger_fns.createTransaction(
amount,
from,
to,
(message) => this.sign(message),
(from, signature, message) => this.overhide_wallet.showOhLedgerGratisIframeUri(uri, from, signature, message),
this.overhide_wallet.oh_ledger_transact_fn[this.mode],
options);

return true;
}
}

export default ohledger_social;
Loading

0 comments on commit 5c4e881

Please sign in to comment.