-
Notifications
You must be signed in to change notification settings - Fork 100
/
googleAuthentication.ts
98 lines (77 loc) 路 2.25 KB
/
googleAuthentication.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import { fromEvent, FunctionEvent } from 'graphcool-lib'
import { GraphQLClient } from 'graphql-request'
import * as fetch from 'isomorphic-fetch'
interface User {
id: string
}
interface GoogleUser {
id: string
email: string | null
}
interface EventData {
googleToken: string
}
export default async (event: FunctionEvent<EventData>) => {
console.log(event)
try {
const graphcool = fromEvent(event)
const api = graphcool.api('simple/v1')
const { googleToken } = event.data
// call google API to obtain user data
const googleUser = await getGoogleUser(googleToken)
// get graphcool user by google id
const user: User = await getGraphcoolUser(api, googleUser.sub)
.then(r => r.User)
// check if graphcool user exists, and create new one if not
let userId: string | null = null
if (!user) {
userId = await createGraphcoolUser(api, googleUser.sub)
} else {
userId = user.id
}
// generate node token for User node
const token = await graphcool.generateAuthToken(userId!, 'User')
return { data: { id: userId, token} }
} catch (e) {
console.log(e)
return { error: 'An unexpected error occured during authentication.' }
}
}
async function getGoogleUser(googleToken: string): Promise<GoogleUser> {
const endpoint = `https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=${googleToken}`
const data = await fetch(endpoint)
.then(response => response.json())
if (data.error_description) {
throw new Error(data.error_description)
}
return data
}
async function getGraphcoolUser(api: GraphQLClient, googleUserId: string): Promise<{ User }> {
const query = `
query getUser($googleUserId: String!) {
User(googleUserId: $googleUserId) {
id
}
}
`
const variables = {
googleUserId,
}
return api.request<{ User }>(query, variables)
}
async function createGraphcoolUser(api: GraphQLClient, googleUserId: string): Promise<string> {
const mutation = `
mutation createUser($googleUserId: String!) {
createUser(
googleUserId: $googleUserId
) {
id
}
}
`
const variables = {
googleUserId,
}
return api.request<{ createUser: User }>(mutation, variables)
.then(r => r.createUser.id)
}