Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Credential Management API and Payment Request API implementations #104

Merged
merged 32 commits into from
Dec 20, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
262fde3
Integrate PaymentRequest (aka Web Payments) into Shop
Aug 26, 2016
d17c730
Merge remote-tracking branch 'upstream/master'
Aug 26, 2016
b1d3aa6
Update announce on order success modal
Aug 26, 2016
c9f04f1
Fix case where redirect loop to /checkout may occur
Aug 31, 2016
52db06d
Factor out most PaymentRequest logic into a component
Sep 26, 2016
c955ddc
Allowing shipping to non-US addresses
Sep 27, 2016
3e9484b
Resolves cart being inadvertently cleared in two scenarios:
Sep 28, 2016
18bb628
Add shop-payment-request to lazy-resources
Oct 19, 2016
5dd8b18
Set methods to full list of options by default, and broaden error han…
Oct 19, 2016
b5d012e
Addressing a few comments from PR:
Oct 19, 2016
9116cac
Simplify CSS for shop-detail
Oct 19, 2016
fada132
Addressing more PR comments:
Oct 19, 2016
2d8c42e
Merge from master
Oct 19, 2016
304e9d0
Adds Credential API and Payment API
agektmr Oct 23, 2016
e4d89fd
Fix for async loading of shop-account
agektmr Oct 24, 2016
71c2db6
Added fetch polifill for Safari
agektmr Oct 24, 2016
8421c33
Added missing change from Fitz's work
agektmr Oct 26, 2016
788576a
Make image user icon circular
agektmr Oct 31, 2016
efa3557
Merge branch 'credential-payment' of https://github.com/agektmr/shop …
Nov 7, 2016
d58bdcf
Merge pull request #1 from afitz0/credentials-payment
agektmr Nov 7, 2016
82519a4
Redirect to /account on successful payment.
Nov 7, 2016
f000723
Redirect to signup page for proper messaging.
Nov 8, 2016
dd7aae1
Merge pull request #2 from afitz0/credentials-payment
agektmr Nov 9, 2016
52fa667
Add PR API params enabled by Chrome 56
agektmr Dec 9, 2016
88f4c91
Remove server code, add auth service worker
agektmr Dec 9, 2016
022809d
Going server-less
agektmr Dec 12, 2016
2daed14
Implemented SW based mock auth server
agektmr Dec 13, 2016
198e4e0
Merge branch 'server-less' into credential-payment
agektmr Dec 13, 2016
cafae25
Support non-service worker enabled browsers.
agektmr Dec 14, 2016
76d4af9
Revert README
agektmr Dec 14, 2016
1988727
Reflect requested changes
agektmr Dec 14, 2016
62b8560
Reflecting feedback
agektmr Dec 15, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ Install [polymer-cli](https://github.com/Polymer/polymer-cli):

npm install -g polymer-cli


##### Setup
# Using CLI
mkdir shop
cd shop
polymer init shop

# Or cloning direct from GitHub
git clone https://github.com/Polymer/shop.git
cd shop
Expand All @@ -38,7 +37,7 @@ Install [polymer-cli](https://github.com/Polymer/polymer-cli):
This command serves the minified version of the app in an unbundled state, as it would be served by a push-compatible server:

polymer serve build/unbundled

This command serves the minified version of the app generated using fragment bundling:

polymer serve build/bundled
37 changes: 0 additions & 37 deletions app.yaml

This file was deleted.

170 changes: 170 additions & 0 deletions auth-mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
var DATABASE_NAME = 'auth_db';
var DB_VERSION = 1;
var OBJECT_STORE_NAME = 'auth_object_store';

self.addEventListener('fetch', function(event) {
var response = null;
var request = event.request.clone();

// Filter everything else but urls starting with `/auth/`.
if (/\/auth\/.*$/.test(request.url)) {
event.respondWith(
// Get POST payload
request.text().then(function(text) {
// Retrieve key:val from payload
var params = multipartFormParser(text);
params.name = params.name || '';
params.id = params.id || params.email;
params.imageUrl = params.imageUrl || '';
params.email = params.email;

// For password authentication
if (/\/auth\/password/.test(request.url)) {
delete params.id_token;
if (!params.email || !params.password) {
return Promise.reject('Bad Request', 400);
} else {
return db.get(params);
}
// For signing up
} else if (/\/auth\/register/.test(request.url)) {
if (!params.email || !params.password) {
return Promise.reject('Bad Request', 400);
} else {
return db.add(params);
}
// For Google Sign-In
} else if (/\/auth\/google/.test(request.url)) {
return verifyIdToken(params.id_token);
}
return Promise.reject();
}).then(function(result) {
// Successful authentication
delete result.password;
var response = new Response(JSON.stringify(result), {
status: 200,
contentType: 'application/json'
});
return response;
}).catch(function(text, status) {
// Authentication failure
var response = new Response(text || 'Authentication failed.', {
status: status || 401,
statusText: text || 'Authentication failed.'
});
return response;
})
);
} else {
event.respondWith(fetch(request));
}
});

// Retrieve multipart form payload and extract POST'ed data.
var multipartFormParser = function(body, param) {
var results = {};
var params = ['id', 'email', 'password', 'name', 'iconURL', 'id_token'];
for (var i in params) {
var param = params[i];
var regex = new RegExp('Content-Disposition: form-data; name="'+param+'"[\\s\\S]{4}(.+)[\\s\\S]', 'm');
var result = regex.exec(body);
if (result) {
results[param] = result[1];
}
}
return results;
};

// Verify Google Id Token with official endpoint.
var verifyIdToken = function(id_token) {
var VERIFY_ENDPOINT = 'https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=';
return fetch(VERIFY_ENDPOINT+id_token)
.then(function(res) {
if (res.status == 200) {
return res.json();
} else {
throw 'Verification failed';
}
}).then(function(data) {
return db.add({
id: data.sub,
email: data.email,
imageUrl: data.picture,
name: data.name
});
});
};

// Simple database implementation that stores authentication information
var DB = function() {
var that = this;
this.isReady = (function() {
return new Promise(function(resolve, reject) {
if (!'indexedDB' in self) {
reject();
}
var req = self.indexedDB.open(DATABASE_NAME, DB_VERSION);
req.onsuccess = function(e) {
that.db = e.target.result;
resolve();
};
req.onerror = function(e) {
reject();
};
req.onblocked = function(e) {
reject();
};
req.onupgradeneeded = function(e) {
that.db = e.target.result;
if (e.oldVersion <= 1) {
that.db.createObjectStore(OBJECT_STORE_NAME, {keyPath: 'id'});
}
};
});
})();
};
DB.prototype.transaction = function() {
var that = this;
return new Promise(function(resolve, reject) {
that.isReady.then(function() {
resolve(that.db.transaction(OBJECT_STORE_NAME, 'readwrite'));
}).catch(function() {
reject();
});
})
}
// Add an account
DB.prototype.add = function(params) {
var that = this;
return new Promise(function(resolve, reject) {
this.db.transaction().then(function(trans) {
var req = trans.objectStore(OBJECT_STORE_NAME).put(params);
req.onsuccess = function(e) {
resolve(params);
};
req.onerror = reject;
trans.onerror = reject;
});
});
};
// Get an account
DB.prototype.get = function(params) {
var that = this;
return new Promise(function(resolve, reject) {
that.transaction().then(function(trans) {
var req = trans.objectStore(OBJECT_STORE_NAME).get(params.id);
req.onsuccess = function(e) {
var profile = e.target.result;
if (profile && profile.password == params.password) {
resolve(profile);
} else {
reject();
}
}
req.onerror = reject;
trans.onerror = reject;
});
});
};

var db = new DB();
4 changes: 3 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
"iron-pages": "polymerelements/iron-pages#^1.0.0",
"iron-selector": "polymerelements/iron-selector#^1.0.0",
"paper-icon-button": "polymerelements/paper-icon-button#^1.0.0",
"paper-spinner": "polymerelements/paper-spinner#^1.0.0"
"paper-spinner": "polymerelements/paper-spinner#^1.0.0",
"fetch": "^1.0.0",
"google-apis": "GoogleWebComponents/google-apis#^1.1.7"
},
"devDependencies": {
"web-component-tester": "^4.0.0"
Expand Down
Binary file added images/google_signin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
<title>SHOP</title>

<link rel="shortcut icon" sizes="32x32" href="/images/shop-icon-32.png">
<meta name="google-signin-client_id" content="569649340112-da0ku71mend03mdsu9h7skmv33r2qkg2.apps.googleusercontent.com">
<script src="/bower_components/fetch/fetch.js" async></script>

<meta name="theme-color" content="#fff">
<link rel="manifest" href="/manifest.json">
Expand Down Expand Up @@ -53,7 +55,7 @@
<body>

<shop-app unresolved>SHOP</shop-app>

<input id="csrf_token" type="hidden" name="csrf_token" value="" />
<script>
window.performance && performance.mark && performance.mark('index.html');

Expand Down
3 changes: 3 additions & 0 deletions polymer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"src/shop-list.html",
"src/shop-detail.html",
"src/shop-cart.html",
"src/shop-account.html",
"src/shop-checkout.html",
"src/lazy-resources.html"
],
Expand All @@ -15,7 +16,9 @@
"bower.json"
],
"includeDependencies": [
"auth-mock.js",
"manifest.json",
"bower_components/fetch/fetch.js",
"bower_components/webcomponentsjs/webcomponents-lite.min.js"
]
}
3 changes: 3 additions & 0 deletions src/lazy-resources.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
<!-- shop-app -->
<link rel="import" href="../bower_components/app-layout/app-drawer/app-drawer.html">
<link rel="import" href="../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="shop-account-data.html">
<link rel="import" href="shop-analytics.html">
<link rel="import" href="shop-cart-data.html">
<link rel="import" href="shop-cart-modal.html">
<link rel="import" href="shop-icons.html">
<link rel="import" href="shop-order-success-modal.html">
<link rel="import" href="shop-snackbar.html">
<link rel="import" href="shop-tabs.html">
<link rel="import" href="shop-tab.html">
<link rel="import" href="shop-payment-request.html">

<!-- shop-home -->

Expand Down
Loading