Skip to content

Commit

Permalink
Migrated LinkedIn authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
kbrandwijk authored and Nilan Marktanner committed Nov 10, 2017
1 parent 5cd065e commit 6b0f8d7
Show file tree
Hide file tree
Showing 13 changed files with 195 additions and 108 deletions.
4 changes: 2 additions & 2 deletions auth/google/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ graphcool add-template graphcool/templates/auth/google

The [`add-template`](https://www.graph.cool/docs/reference/graphcool-cli/commands-aiteerae6l#graphcool-add-template) command is performing three major steps:

1. Download the source files from the [`src`](./src) directory and put them into your service's `src` directory (into a subdirectory called `email-password`).
1. Download the source files from the [`src`](./src) directory and put them into your service's `src` directory (into a subdirectory called `google`).
2. Download the contents from [`graphcool.yml`](./graphcool.yml) and append them as comments to your service's `graphcool.yml`.
3. Download the contents from [`types.graphql`](./types.graphql) and append them as comments to your service's `types.graphql`.

Expand Down Expand Up @@ -73,7 +73,7 @@ Run this mutation to authenticate a user:
```graphql
mutation {
# replace __GOOGLE_TOKEN__!
authenticateUser(googleToken: "__GOOGLE_TOKEN__") {
authenticateGoogleUser(googleToken: "__GOOGLE_TOKEN__") {
token
}
}
Expand Down
72 changes: 72 additions & 0 deletions auth/linkedin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# linkedin-authentication

Add LinkedIn Authentication to your Graphcool project 🎁

## Getting Started

### 1. Add the template to your Graphcool service

```sh
graphcool add-template graphcool/templates/auth/linkedin
```

### 2. Uncomment lines in `graphcool.yml` and `types.graphql`

The [`add-template`](https://www.graph.cool/docs/reference/graphcool-cli/commands-aiteerae6l#graphcool-add-template) command is performing three major steps:

1. Download the source files from the [`src`](./src) directory and put them into your service's `src` directory (into a subdirectory called `linkedin`).
2. Download the contents from [`graphcool.yml`](./graphcool.yml) and append them as comments to your service's `graphcool.yml`.
3. Download the contents from [`types.graphql`](./types.graphql) and append them as comments to your service's `types.graphql`.

In order for the changes to take effect, you need to manually uncomment all the lines that have been added by the `add-template` command.

### 3. Deploy the service

Finally, you need to install the [node dependencies](./package.json#L2) and apply all the changes you just made by deploying the service:

```sh
npm install
graphcool deploy
```

## Configuration

To use LinkedIn Authentication you need to create a LinkedIn app.

Once you created a new App, copy its Client-id. Replace `__CLIENT_ID__` in `login.html` with your Client-id.

Add `http://localhost:8000` and `http://localhost:8000/login.html` to your valid OAuth 2.0 URLs.
Add `http://localhost:8000` to your valid Javascript SDK domains.

Copy the Client ID and use it to replace `__CLIENT_ID__` in `login.html`.

To create a test LinkedIn Token, run `login.html`, for example using Python's `SimpleHTTPServer`:

```sh
python -m SimpleHTTPServer
```

Open `http://localhost:8000/login.html` in your browser and use the login button to create a new LinkedIn Token. It will be printed in the DevTools.

## Test the Code

First, obtain a valid LinkedIn token with the small app in `login.html` as mentioned above.

Go to the Graphcool Playground:

```sh
graphcool playground
```

Run this mutation to authenticate a user:

```graphql
mutation {
# replace __LINKEDIN_TOKEN__!
authenticateLinkedInUser(linkedInToken: "__LINKEDIN_TOKEN__") {
token
}
}
```

You should see that a new user has been created. The returned token can be used to authenticate requests to your Graphcool API as that user. Note that running the mutation again with the same LinkedIn token will not add a new user.
15 changes: 15 additions & 0 deletions auth/linkedin/graphcool.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
types: ./types.graphql

functions:
linkedInAuthentication:
handler:
code:
src: ./src/linkedInAuthentication.ts
type: resolver
schema: ./src/linkedInAuthentication.graphql
loggedInUser:
handler:
code:
src: ./src/loggedInUser.ts
type: resolver
schema: ./src/loggedInUser.graphql
26 changes: 26 additions & 0 deletions auth/linkedin/login.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<html>

<head>
<script type="text/javascript" src="//platform.linkedin.com/in.js">
api_key: __CLIENT_ID__
authorize: true
onLoad: onLinkedInLoad
</script>

<script type="text/javascript">
function onLinkedInLoad() {
IN.Event.on(IN, "auth", authenticateUser);
}

function authenticateUser() {
console.log('Token: ', IN.ENV.auth.oauth_token)
// call Graphcool authenticateLinkedInUser mutation
}
</script>
</head>

<body>
<script type="in/Login"></script>
</body>

</html>
9 changes: 9 additions & 0 deletions auth/linkedin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"dependencies": {
"graphcool-lib": "^0.1.0",
"graphql-request": "^1.4.0"
},
"devDependencies": {
"@types/node": "^8.0.44"
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
'use latest'

const { fromEvent } = require('graphcool-lib')

module.exports = function(event) {
Expand Down Expand Up @@ -45,8 +43,7 @@ module.exports = function(event) {
}

function generateGraphcoolToken(graphcoolUserId) {
console.log(`graphcooluserid ${graphcoolUserId}`)
return graphcool.generateAuthToken(graphcoolUserId, 'User')
return graphcool.generateNodeToken(graphcoolUserId, 'User')
}

return getLinkedInAccountData(linkedInToken)
Expand Down
8 changes: 8 additions & 0 deletions auth/linkedin/src/loggedInUser.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
type LoggedInUserPayload {
id: ID!
}

extend type Query {
# return user data if request contains valid authentication token
loggedInUser: LoggedInUserPayload
}
51 changes: 51 additions & 0 deletions auth/linkedin/src/loggedInUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { fromEvent, FunctionEvent } from 'graphcool-lib'
import { GraphQLClient } from 'graphql-request'

interface User {
id: string
}

export default async (event: FunctionEvent<{}>) => {
console.log(event)

try {
// no logged in user
if (!event.context.auth || !event.context.auth.nodeId) {
return { data: null }
}

const userId = event.context.auth.nodeId
const graphcool = fromEvent(event)
const api = graphcool.api('simple/v1')

// get user by id
const user: User = await getUser(api, userId)
.then(r => r.User)

// no logged in user
if (!user || !user.id) {
return { data: null }
}

return { data: { id: user.id } }
} catch (e) {
console.log(e)
return { error: 'An unexpected error occured during authentication.' }
}
}

async function getUser(api: GraphQLClient, id: string): Promise<{ User }> {
const query = `
query getUser($id: ID!) {
User(id: $id) {
id
}
}
`

const variables = {
id,
}

return api.request<{ User }>(query, variables)
}
11 changes: 11 additions & 0 deletions auth/linkedin/types.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
type User {
# Required system field:
id: ID! @isUnique # read-only (managed by Graphcool)

# Optional system fields (remove if not needed):
createdAt: DateTime! # read-only (managed by Graphcool)
updatedAt: DateTime! # read-only (managed by Graphcool)

# Make it required if LinkedIn is the only authorization method in your app
linkedInUserId: String @isUnique
}
72 changes: 0 additions & 72 deletions outdated/auth/linkedin-authentication/README.md

This file was deleted.

This file was deleted.

23 changes: 0 additions & 23 deletions outdated/auth/linkedin-authentication/login.html

This file was deleted.

0 comments on commit 6b0f8d7

Please sign in to comment.