summaryrefslogtreecommitdiffstats
path: root/graphcool/src
diff options
context:
space:
mode:
Diffstat (limited to 'graphcool/src')
-rw-r--r--graphcool/src/auth0/auth0Authentication.graphql8
-rw-r--r--graphcool/src/auth0/auth0Authentication.js104
-rw-r--r--graphcool/src/createCharge.js52
-rw-r--r--graphcool/src/createCharge.test.js23
-rw-r--r--graphcool/src/getPrice.js26
-rw-r--r--graphcool/src/hello.graphql7
-rw-r--r--graphcool/src/hello.js11
-rw-r--r--graphcool/src/index.js2
8 files changed, 233 insertions, 0 deletions
diff --git a/graphcool/src/auth0/auth0Authentication.graphql b/graphcool/src/auth0/auth0Authentication.graphql
new file mode 100644
index 0000000..823a71b
--- /dev/null
+++ b/graphcool/src/auth0/auth0Authentication.graphql
@@ -0,0 +1,8 @@
+type AuthenticateUserPayload {
+ id: String!
+ token: String!
+}
+
+extend type Mutation {
+ authenticateUser(accessToken: String!): AuthenticateUserPayload
+}
diff --git a/graphcool/src/auth0/auth0Authentication.js b/graphcool/src/auth0/auth0Authentication.js
new file mode 100644
index 0000000..4e1b4fa
--- /dev/null
+++ b/graphcool/src/auth0/auth0Authentication.js
@@ -0,0 +1,104 @@
+const isomorphicFetch = require('isomorphic-fetch');
+const jwt = require('jsonwebtoken');
+const jwkRsa = require('jwks-rsa');
+const fromEvent = require('graphcool-lib').fromEvent;
+
+//Validates the request JWT token
+const verifyToken = token =>
+ new Promise(resolve => {
+ //Decode the JWT Token
+ const decoded = jwt.decode(token, { complete: true });
+ if (!decoded || !decoded.header || !decoded.header.kid) {
+ throw new Error('Unable to retrieve key identifier from token');
+ }
+ if (decoded.header.alg !== 'RS256') {
+ throw new Error(
+ `Wrong signature algorithm, expected RS256, got ${decoded.header.alg}`
+ );
+ }
+ const jkwsClient = jwkRsa({
+ cache: true,
+ jwksUri: `https://${process.env.AUTH0_DOMAIN}/.well-known/jwks.json`
+ });
+ //Retrieve the JKWS's signing key using the decode token's key identifier (kid)
+ jkwsClient.getSigningKey(decoded.header.kid, (err, key) => {
+ if (err) throw new Error(err);
+ const signingKey = key.publicKey || key.rsaPublicKey;
+ //If the JWT Token was valid, verify its validity against the JKWS's signing key
+ jwt.verify(
+ token,
+ signingKey,
+ {
+ algorithms: ['RS256'],
+ audience: process.env.AUTH0_API_IDENTIFIER,
+ ignoreExpiration: false,
+ issuer: `https://${process.env.AUTH0_DOMAIN}/`
+ },
+ (err, decoded) => {
+ if (err) throw new Error(err);
+ return resolve(decoded);
+ }
+ );
+ });
+ });
+
+//Retrieves the Graphcool user record using the Auth0 user id
+const getGraphcoolUser = (auth0UserId, api) =>
+ api
+ .request(
+ `
+ query getUser($auth0UserId: String!){
+ User(auth0UserId: $auth0UserId){
+ id
+ }
+ }
+ `,
+ { auth0UserId }
+ )
+ .then(queryResult => queryResult.User);
+
+//Creates a new User record.
+const createGraphCoolUser = ({ sub }, api) =>
+ api
+ .request(
+ `
+ mutation createUser($auth0UserId: String!) {
+ createUser(
+ auth0UserId: $auth0UserId
+ ){
+ id
+ }
+ }
+ `,
+ { auth0UserId: sub }
+ )
+ .then(queryResult => queryResult.createUser);
+
+export default async event => {
+ try {
+ if (!process.env.AUTH0_DOMAIN || !process.env.AUTH0_API_IDENTIFIER) {
+ throw new Error(
+ 'Missing AUTH0_DOMAIN or AUTH0_API_IDENTIFIER environment variable'
+ );
+ }
+ const { accessToken } = event.data;
+
+ const decodedToken = await verifyToken(accessToken);
+ const graphcool = fromEvent(event);
+ const api = graphcool.api('simple/v1');
+
+ let graphCoolUser = null;
+
+ graphCoolUser = await getGraphcoolUser(decodedToken.sub, api);
+ //If the user doesn't exist. a new record is created.
+ if (graphCoolUser === null) {
+ graphCoolUser = await createGraphCoolUser(decodedToken, api);
+ }
+ const token = await graphcool.generateAuthToken(graphCoolUser.id, 'User');
+
+ return { data: { id: graphCoolUser.id, token } };
+ } catch (err) {
+ console.log(err);
+ return { error: 'An unexpected error occured' };
+ }
+};
diff --git a/graphcool/src/createCharge.js b/graphcool/src/createCharge.js
new file mode 100644
index 0000000..ccf9c11
--- /dev/null
+++ b/graphcool/src/createCharge.js
@@ -0,0 +1,52 @@
+const stripe = require('stripe')('sk_ycLkGc2cAaBDSCKkHiKVBeT71CMxd');
+
+const endpoint = 'https://api.graph.cool/simple/v1/cj99zm6ye06sb01325ic751ww';
+
+require('isomorphic-fetch');
+
+const getPrice = itemId => {
+ const query = `
+ query SingleItem {
+ Item(id: "${itemId}") {
+ price
+ }
+ }
+ `;
+
+ return fetch(endpoint, {
+ method: 'post',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ query }),
+ });
+};
+
+const createStripeCharge = (token, amount) =>
+ stripe.charges.create({
+ amount,
+ currency: 'usd',
+ description: `a test charge`,
+ source: token,
+ });
+
+module.exports = function(event) {
+ return new Promise((resolve, reject) => {
+ // first find out the price of the item
+ getPrice(event.data.itemId)
+ .then(res => res.json())
+ .then(res => {
+ console.log(`Back with the price ${res.data.Item.price}!`);
+ return createStripeCharge(event.data.token, res.data.Item.price);
+ })
+ .then(res => {
+ console.log(`Back! charge ${res.id} for the amount ${res.amount}`);
+ event.data.charge = res.id;
+ event.data.amount = res.amount;
+ resolve(event);
+ })
+ .catch(err => {
+ reject(err);
+ });
+ });
+};
diff --git a/graphcool/src/createCharge.test.js b/graphcool/src/createCharge.test.js
new file mode 100644
index 0000000..65dde47
--- /dev/null
+++ b/graphcool/src/createCharge.test.js
@@ -0,0 +1,23 @@
+const takeMoney = require('./createCharge');
+
+const event = {
+ "data": {
+ "user": "cj6ntm8qic3260140vkuzif9d",
+ "token": "tok_visa",
+ },
+ "context": {
+ "headers": {}
+ }
+}
+
+
+describe('Take Money', () => {
+
+ test('A charge has come back', async () => {
+ const res = await takeMoney(event);
+ console.log(res);
+ expect(res.data.amount).toBeGreaterThanOrEqual(0);
+ });
+
+});
+
diff --git a/graphcool/src/getPrice.js b/graphcool/src/getPrice.js
new file mode 100644
index 0000000..7808a85
--- /dev/null
+++ b/graphcool/src/getPrice.js
@@ -0,0 +1,26 @@
+require('isomorphic-fetch')
+
+const query = `
+query SingleItem {
+ Item(id: "cj64bs7vuuqgu0116ul5cm223") {
+ price
+ }
+}
+`;
+
+function getItem(id) {
+ return fetch('https://api.graph.cool/simple/v1/cj5xz8szs28930145gct82bdj', {
+ method: 'post',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ query }),
+ })
+}
+
+
+module.exports = function(event) {
+ getItem().then(x => x.json()).then(res => {
+ console.log(res.data.Item.price);
+ }).catch(console.log)
+}
diff --git a/graphcool/src/hello.graphql b/graphcool/src/hello.graphql
new file mode 100644
index 0000000..d43c729
--- /dev/null
+++ b/graphcool/src/hello.graphql
@@ -0,0 +1,7 @@
+type HelloPayload {
+ message: String!
+}
+
+extend type Query {
+ hello(name: String): HelloPayload
+}
diff --git a/graphcool/src/hello.js b/graphcool/src/hello.js
new file mode 100644
index 0000000..0e3e7ba
--- /dev/null
+++ b/graphcool/src/hello.js
@@ -0,0 +1,11 @@
+export default async event => {
+ // you can use ES7 with async/await and even TypeScript in your functions :)
+
+ await new Promise(r => setTimeout(r, 50))
+
+ return {
+ data: {
+ message: `Hello ${event.data.name || 'World'}`
+ }
+ }
+} \ No newline at end of file
diff --git a/graphcool/src/index.js b/graphcool/src/index.js
new file mode 100644
index 0000000..ee451f6
--- /dev/null
+++ b/graphcool/src/index.js
@@ -0,0 +1,2 @@
+module.exports = () => 'Welcome to Micro'
+exports.what = () => 'What'