-
Notifications
You must be signed in to change notification settings - Fork 3
/
apollo_gql.ts
125 lines (108 loc) · 3.3 KB
/
apollo_gql.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import { ApolloServer } from 'apollo-server-lambda'
import {
APIGatewayProxyHandler,
APIGatewayProxyEvent,
Context as LambdaContext,
} from 'aws-lambda'
import typeDefs from '../../app-graphql/src/schema.graphql'
import {
assertIsAuthMode,
CognitoUserType,
} from '../../app-web/src/common-code/domain-models'
import { newDeployedStore, newLocalStore } from '../store'
import { configureResolvers } from '../resolvers'
import {
userFromLocalAuthProvider,
userFromCognitoAuthProvider,
} from '../authn'
// Configuration:
const authMode = process.env.REACT_APP_AUTH_MODE
assertIsAuthMode(authMode)
const getDynamoStore = () => {
const dynamoConnection = process.env.DYNAMO_CONNECTION
const stageName = process.env.stage
const dbPrefix = stageName + '-'
if (dynamoConnection === 'USE_AWS') {
return newDeployedStore(
process.env.AWS_DEFAULT_REGION || 'no region',
dbPrefix
)
} else {
return newLocalStore(process.env.DYNAMO_CONNECTION || 'no db url')
}
}
const store = getDynamoStore()
const userFetcher =
authMode === 'LOCAL'
? userFromLocalAuthProvider
: userFromCognitoAuthProvider
// End Configuration
// Resolvers are defined and tested in the resolvers package
const resolvers = configureResolvers(store)
export interface Context {
user: CognitoUserType
}
const context = async ({
event,
}: {
event: APIGatewayProxyEvent
context: LambdaContext
}): Promise<Context> => {
const authProvider =
event.requestContext.identity.cognitoAuthenticationProvider
if (authProvider) {
try {
const userResult = await userFetcher(authProvider)
if (!userResult.isErr()) {
return {
user: userResult.value,
}
} else {
throw new Error(
`Log: failed to fetch user: ${userResult.error}`
)
}
} catch (err) {
console.log('Error attempting to fetch user: ', err)
throw new Error('Log: placing user in gql context failed')
}
} else {
throw new Error('Log: no AuthProvider')
}
}
const server = new ApolloServer({
typeDefs,
resolvers,
context,
})
function localAuthMiddleware(
wrapped: APIGatewayProxyHandler
): APIGatewayProxyHandler {
return function (event, context, completion) {
const userHeader =
event.requestContext.identity.cognitoAuthenticationProvider
if (userHeader === 'NO_USER') {
console.log('NO_USER info set, returning 403')
return Promise.resolve({
statusCode: 403,
body:
'{ "error": "No User Sent in cognitoAuthenticationProvider header"}\n',
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': true,
},
})
}
return wrapped(event, context, completion)
}
}
const gqlHandler = server.createHandler({
expressGetMiddlewareOptions: {
cors: {
origin: true,
credentials: true,
},
},
})
const isLocal = authMode === 'LOCAL'
exports.graphqlHandler = isLocal ? localAuthMiddleware(gqlHandler) : gqlHandler