@@ -4,22 +4,37 @@ import { Model } from 'objection'
44import { Config } from './config/app'
55import { App , AppServices } from './app'
66import createLogger from 'pino'
7+ import {
8+ ApolloClient ,
9+ ApolloLink ,
10+ createHttpLink ,
11+ InMemoryCache
12+ } from '@apollo/client'
13+ import { onError } from '@apollo/client/link/error'
14+ import { setContext } from '@apollo/client/link/context'
15+ import { print } from 'graphql'
16+ import { canonicalize } from 'json-canonicalize'
17+ import { createHmac } from 'crypto'
718import { createMerchantService } from './merchant/service'
819import { createPosDeviceService } from './merchant/devices/service'
920import { createMerchantRoutes } from './merchant/routes'
21+ import { createPaymentService } from './payments/service'
1022import { createPosDeviceRoutes } from './merchant/devices/routes'
1123
1224export function initIocContainer (
1325 config : typeof Config
1426) : IocContract < AppServices > {
1527 const container : IocContract < AppServices > = new Ioc ( )
28+
1629 container . singleton ( 'config' , async ( ) => config )
30+
1731 container . singleton ( 'logger' , async ( deps : IocContract < AppServices > ) => {
1832 const config = await deps . use ( 'config' )
1933 const logger = createLogger ( )
2034 logger . level = config . logLevel
2135 return logger
2236 } )
37+
2338 container . singleton ( 'knex' , async ( deps : IocContract < AppServices > ) => {
2439 const logger = await deps . use ( 'logger' )
2540 const config = await deps . use ( 'config' )
@@ -76,6 +91,89 @@ export function initIocContainer(
7691 } )
7792 } )
7893
94+ container . singleton ( 'apolloClient' , async ( deps ) => {
95+ const [ logger , config ] = await Promise . all ( [
96+ deps . use ( 'logger' ) ,
97+ deps . use ( 'config' )
98+ ] )
99+
100+ const httpLink = createHttpLink ( {
101+ uri : config . graphqlUrl
102+ } )
103+
104+ const errorLink = onError ( ( { graphQLErrors } ) => {
105+ if ( graphQLErrors ) {
106+ logger . error ( graphQLErrors )
107+ graphQLErrors . map ( ( { extensions } ) => {
108+ if ( extensions && extensions . code === 'UNAUTHENTICATED' ) {
109+ logger . error ( 'UNAUTHENTICATED' )
110+ }
111+
112+ if ( extensions && extensions . code === 'FORBIDDEN' ) {
113+ logger . error ( 'FORBIDDEN' )
114+ }
115+ } )
116+ }
117+ } )
118+
119+ const authLink = setContext ( ( request , { headers } ) => {
120+ if ( ! config . tenantSecret || ! config . tenantSignatureVersion )
121+ return { headers }
122+ const timestamp = Date . now ( )
123+ const version = config . tenantSignatureVersion
124+
125+ const { query, variables, operationName } = request
126+ const formattedRequest = {
127+ variables,
128+ operationName,
129+ query : print ( query )
130+ }
131+
132+ const payload = `${ timestamp } .${ canonicalize ( formattedRequest ) } `
133+ const hmac = createHmac ( 'sha256' , config . tenantSecret )
134+ hmac . update ( payload )
135+ const digest = hmac . digest ( 'hex' )
136+
137+ const link = {
138+ headers : {
139+ ...headers ,
140+ 'tenant-id' : `${ config . tenantId } ` ,
141+ signature : `t=${ timestamp } , v${ version } =${ digest } `
142+ }
143+ }
144+
145+ return link
146+ } )
147+
148+ const link = ApolloLink . from ( [ errorLink , authLink , httpLink ] )
149+
150+ const client = new ApolloClient ( {
151+ cache : new InMemoryCache ( { } ) ,
152+ link : link ,
153+ defaultOptions : {
154+ query : {
155+ fetchPolicy : 'no-cache'
156+ } ,
157+ mutate : {
158+ fetchPolicy : 'no-cache'
159+ } ,
160+ watchQuery : {
161+ fetchPolicy : 'no-cache'
162+ }
163+ }
164+ } )
165+
166+ return client
167+ } )
168+
169+ container . singleton ( 'paymentClient' , async ( deps ) => {
170+ return createPaymentService ( {
171+ apolloClient : await deps . use ( 'apolloClient' ) ,
172+ logger : await deps . use ( 'logger' ) ,
173+ config : await deps . use ( 'config' )
174+ } )
175+ } )
176+
79177 container . singleton (
80178 'posDeviceService' ,
81179 async ( deps : IocContract < AppServices > ) => {
@@ -94,6 +192,7 @@ export function initIocContainer(
94192 posDeviceService : await deps . use ( 'posDeviceService' )
95193 } )
96194 )
195+
97196 return container
98197}
99198
0 commit comments