@things-factory/integration-accounting 8.0.0-beta.9 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist-server/tsconfig.tsbuildinfo +1 -1
  2. package/package.json +14 -14
  3. package/server/controllers/accounting-api/decorators.ts +47 -0
  4. package/server/controllers/accounting-api/index.ts +72 -0
  5. package/server/controllers/index.ts +3 -0
  6. package/server/controllers/xero/apis/contact/get-contact.ts +38 -0
  7. package/server/controllers/xero/apis/contact/get-contacts.ts +16 -0
  8. package/server/controllers/xero/apis/contact/index.ts +2 -0
  9. package/server/controllers/xero/apis/index.ts +4 -0
  10. package/server/controllers/xero/apis/invoice/create-invoice.ts +12 -0
  11. package/server/controllers/xero/apis/invoice/get-invoice.ts +14 -0
  12. package/server/controllers/xero/apis/invoice/get-invoices.ts +76 -0
  13. package/server/controllers/xero/apis/invoice/index.ts +4 -0
  14. package/server/controllers/xero/apis/invoice/update-invoice.ts +12 -0
  15. package/server/controllers/xero/apis/item/create-item.ts +37 -0
  16. package/server/controllers/xero/apis/item/delete-item.ts +19 -0
  17. package/server/controllers/xero/apis/item/get-item.ts +41 -0
  18. package/server/controllers/xero/apis/item/get-items.ts +41 -0
  19. package/server/controllers/xero/apis/item/index.ts +6 -0
  20. package/server/controllers/xero/apis/item/update-item.ts +35 -0
  21. package/server/controllers/xero/apis/item/update-items.ts +43 -0
  22. package/server/controllers/xero/apis/purchase-order/get-purchase-orders.ts +61 -0
  23. package/server/controllers/xero/apis/purchase-order/index.ts +1 -0
  24. package/server/controllers/xero/index.ts +8 -0
  25. package/server/controllers/xero/platform-action.ts +53 -0
  26. package/server/controllers/xero/xero.ts +215 -0
  27. package/server/engine/connector/accounting-connector.ts +33 -0
  28. package/server/engine/connector/index.ts +1 -0
  29. package/server/engine/index.ts +2 -0
  30. package/server/engine/task/accounting-api.ts +64 -0
  31. package/server/engine/task/index.ts +1 -0
  32. package/server/entities/account.ts +86 -0
  33. package/server/entities/index.ts +5 -0
  34. package/server/graphql/index.ts +7 -0
  35. package/server/graphql/resolvers/accounting/account.ts +14 -0
  36. package/server/graphql/resolvers/accounting/accounts.ts +15 -0
  37. package/server/graphql/resolvers/accounting/create-account.ts +18 -0
  38. package/server/graphql/resolvers/accounting/delete-account.ts +20 -0
  39. package/server/graphql/resolvers/accounting/delete-accounts.ts +25 -0
  40. package/server/graphql/resolvers/accounting/index.ts +25 -0
  41. package/server/graphql/resolvers/accounting/update-account.ts +18 -0
  42. package/server/graphql/resolvers/accounting/update-multiple-accounts.ts +44 -0
  43. package/server/graphql/resolvers/accounting/xero/deactivate-xero-account.ts +57 -0
  44. package/server/graphql/resolvers/accounting/xero/get-xero-auth-url.ts +32 -0
  45. package/server/graphql/resolvers/accounting/xero/index.ts +13 -0
  46. package/server/graphql/resolvers/accounting/xero/refresh-xero-access-token.ts +67 -0
  47. package/server/graphql/resolvers/accounting-api/accounting-invoice.ts +36 -0
  48. package/server/graphql/resolvers/accounting-api/accounting-item.ts +42 -0
  49. package/server/graphql/resolvers/accounting-api/accounting-purchase-order.ts +14 -0
  50. package/server/graphql/resolvers/accounting-api/index.ts +14 -0
  51. package/server/graphql/resolvers/index.ts +5 -0
  52. package/server/graphql/types/accounting/account-list.ts +8 -0
  53. package/server/graphql/types/accounting/account-patch.ts +14 -0
  54. package/server/graphql/types/accounting/account.ts +25 -0
  55. package/server/graphql/types/accounting/index.ts +44 -0
  56. package/server/graphql/types/accounting/new-account.ts +12 -0
  57. package/server/graphql/types/accounting-api/invoice.ts +65 -0
  58. package/server/graphql/types/accounting-api/item.ts +64 -0
  59. package/server/graphql/types/accounting-api/purchase-order.ts +30 -0
  60. package/server/graphql/types/index.ts +10 -0
  61. package/server/index.ts +9 -0
  62. package/server/migrations/index.ts +9 -0
  63. package/server/routers/xero-private-router.ts +24 -0
  64. package/server/routers/xero-router.ts +154 -0
  65. package/server/routes.ts +10 -0
@@ -0,0 +1,57 @@
1
+ import fetch from 'node-fetch'
2
+
3
+ import { getRepository } from '@things-factory/shell'
4
+
5
+ import { ACCOUNTING_STATUS } from '../../../../controllers'
6
+ import { Account } from '../../../../entities'
7
+
8
+ const debug = require('debug')('things-factory:integration-accounting:deactivate-xero-account')
9
+
10
+ export const deactivateXeroAccount = {
11
+ async deactivateXeroAccount(_: any, { id }, context: ResolverContext) {
12
+ const repository = getRepository(Account)
13
+ const account: any = await repository.findOne({
14
+ where: { domain: { id: context.state.domain.id }, id }
15
+ })
16
+
17
+ try {
18
+ const connection = JSON.parse(account.accountInfo)
19
+
20
+ if (connection) {
21
+ /* delete connection request to xero */
22
+ const response = await fetch(`https://api.xero.com/connections/${connection.id}`, {
23
+ method: 'delete',
24
+ headers: {
25
+ Authorization: `Bearer ${account.accessToken}`
26
+ }
27
+ })
28
+
29
+ if (!response.ok) {
30
+ debug('delete connection failed', response.status, await response.text())
31
+ }
32
+ } else {
33
+ debug(`connection info from accountInfo is empty`)
34
+ }
35
+ } catch (err) {
36
+ debug(`get connection info failed from accountInfo`)
37
+ }
38
+
39
+ var patch = {
40
+ accountId: '',
41
+ accessToken: '',
42
+ refreshToken: '',
43
+ accessInfo: '',
44
+ expiresIn: null,
45
+ tokenType: '',
46
+ accountInfo: '',
47
+ countryCode: '',
48
+ status: ACCOUNTING_STATUS.INACTIVE
49
+ }
50
+
51
+ return await repository.save({
52
+ ...account,
53
+ ...patch,
54
+ updater: context.state.user
55
+ })
56
+ }
57
+ }
@@ -0,0 +1,32 @@
1
+ import crypto from 'crypto'
2
+
3
+ import { VerificationToken, VerificationTokenType } from '@things-factory/auth-base'
4
+ import { config } from '@things-factory/env'
5
+ import { getRepository } from '@things-factory/shell'
6
+
7
+ import { Xero } from '../../../../controllers/xero'
8
+
9
+ const xeroConfig = config.get('accountingIntegrationXero', {})
10
+ const { apiKey, apiSecret, callback } = xeroConfig
11
+
12
+ export function makeVerificationTokenForNonce() {
13
+ return crypto.randomBytes(16).toString('hex')
14
+ }
15
+
16
+ export const getXeroAuthURL = {
17
+ async getXeroAuthURL(_: any, { accounting }, context: ResolverContext) {
18
+ const { user } = context.state
19
+ const xero = new Xero({ apiKey, apiSecret, callback })
20
+
21
+ /* generate verification-token as a nonce */
22
+ const nonce = makeVerificationTokenForNonce()
23
+ await getRepository(VerificationToken).save({
24
+ userId: user.id,
25
+ token: nonce,
26
+ type: VerificationTokenType.REQUEST_ACCESS_TOKEN,
27
+ suppliment: accounting
28
+ })
29
+
30
+ return xero.buildAuthURL(nonce)
31
+ }
32
+ }
@@ -0,0 +1,13 @@
1
+ import { getXeroAuthURL } from './get-xero-auth-url'
2
+
3
+ import { deactivateXeroAccount } from './deactivate-xero-account'
4
+ import { refreshXeroAccessToken } from './refresh-xero-access-token'
5
+
6
+ export const Query = {
7
+ ...getXeroAuthURL
8
+ }
9
+
10
+ export const Mutation = {
11
+ ...refreshXeroAccessToken,
12
+ ...deactivateXeroAccount
13
+ }
@@ -0,0 +1,67 @@
1
+ import fetch from 'node-fetch'
2
+
3
+ import { config } from '@things-factory/env'
4
+ import { getRepository } from '@things-factory/shell'
5
+ import { parseJwt } from '@things-factory/utils'
6
+
7
+ import { Account } from '../../../../entities'
8
+
9
+ const xeroConfig = config.get('accountingIntegrationXero', {})
10
+ const { apiKey, apiSecret } = xeroConfig
11
+
12
+ const debug = require('debug')('things-factory:integration-accounting:refresh-xero-access-token')
13
+
14
+ export const refreshXeroAccessToken = {
15
+ async refreshXeroAccessToken(_: any, { id }, context: ResolverContext) {
16
+ const repository = getRepository(Account)
17
+ const account: any = await repository.findOne({
18
+ where: { domain: { id: context.state.domain.id }, id }
19
+ })
20
+
21
+ const refreshRequestData = {
22
+ grant_type: 'refresh_token',
23
+ refresh_token: account.refreshToken
24
+ }
25
+
26
+ const refreshResponse = await fetch(`https://identity.xero.com/connect/token`, {
27
+ method: 'post',
28
+ headers: {
29
+ Authorization: `Basic ${Buffer.from(apiKey + ':' + apiSecret).toString('base64')}`,
30
+ 'Content-Type': 'application/x-www-form-urlencoded'
31
+ },
32
+ body: Object.entries(refreshRequestData)
33
+ .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))
34
+ .join('&')
35
+ })
36
+
37
+ if (!refreshResponse.ok) {
38
+ throw new Error(`get account information failed: ${await refreshResponse.text()}`)
39
+ }
40
+
41
+ const body = await refreshResponse.json()
42
+ const {
43
+ access_token /* token used to call the API */,
44
+ id_token /* token containing user identity details (only returned if OpenID Connect scopes are requested) */,
45
+ expires_in /* amount of seconds until the access token expires */,
46
+ token_type: tokenType /* must be Bearer */,
47
+ refresh_token
48
+ /* token used to refresh the access token once it has expired (only returned if the offline_access scope is requested).
49
+ */
50
+ } = body
51
+
52
+ const { exp } = parseJwt(access_token)
53
+
54
+ var patch = {
55
+ accessToken: access_token,
56
+ refreshToken: refresh_token,
57
+ tokenType,
58
+ expiresIn: new Date(exp * 1000)
59
+ }
60
+
61
+ return await repository.save({
62
+ ...account,
63
+ ...patch,
64
+ updater: context.state.user
65
+ })
66
+ }
67
+ }
@@ -0,0 +1,36 @@
1
+ import { AccountingAPI } from '../../../controllers/accounting-api'
2
+
3
+ export const queryAccountingInvoice = {
4
+ async getAccountingInvoices(_: any, { accountingId, params: ListParam }, context: ResolverContext) {
5
+ var accounting = await AccountingAPI.getAccounting(accountingId)
6
+
7
+ return await AccountingAPI.getInvoices(accounting, {
8
+ pagination: {
9
+ page: 0,
10
+ limit: 100
11
+ }
12
+ })
13
+ },
14
+
15
+ async getAccountingInvoice(_: any, { accountingId, invoiceNo }, context: ResolverContext) {
16
+ var accounting = await AccountingAPI.getAccounting(accountingId)
17
+
18
+ return await AccountingAPI.getInvoice(accounting, {
19
+ invoiceNo
20
+ })
21
+ }
22
+ }
23
+
24
+ export const mutateAccountingInvoice = {
25
+ async createAccountingInvoice(_: any, { accountingId, newInvoice }, context: ResolverContext) {
26
+ var accounting = await AccountingAPI.getAccounting(accountingId)
27
+
28
+ return await AccountingAPI.createInvoice(accounting, newInvoice)
29
+ },
30
+
31
+ async updateAccountingInvoice(_: any, { accountingId, patch }, context: ResolverContext) {
32
+ var accounting = await AccountingAPI.getAccounting(accountingId)
33
+
34
+ return await AccountingAPI.updateInvoice(accounting, patch)
35
+ }
36
+ }
@@ -0,0 +1,42 @@
1
+ import { AccountingAPI } from '../../../controllers/accounting-api'
2
+
3
+ export const queryAccountingItem = {
4
+ async getAccountingItems(_: any, { accountingId, params: ListParam }, context: ResolverContext) {
5
+ var accounting = await AccountingAPI.getAccounting(accountingId)
6
+
7
+ return await AccountingAPI.getItems(accounting, {
8
+ pagination: {
9
+ page: 0,
10
+ limit: 100
11
+ }
12
+ })
13
+ },
14
+
15
+ async getAccountingItem(_: any, { accountingId, itemId }, context: ResolverContext) {
16
+ var accounting = await AccountingAPI.getAccounting(accountingId)
17
+
18
+ return await AccountingAPI.getItem(accounting, {
19
+ itemId
20
+ })
21
+ }
22
+ }
23
+
24
+ export const mutateAccountingItem = {
25
+ async createAccountingItem(_: any, { accountingId, newItem }, context: ResolverContext) {
26
+ var accounting = await AccountingAPI.getAccounting(accountingId)
27
+
28
+ return await AccountingAPI.createItem(accounting, newItem)
29
+ },
30
+
31
+ async updateAccountingItem(_: any, { accountingId, patch }, context: ResolverContext) {
32
+ var accounting = await AccountingAPI.getAccounting(accountingId)
33
+
34
+ return await AccountingAPI.updateItem(accounting, patch)
35
+ },
36
+
37
+ async deleteAccountingItem(_: any, { accountingId, itemId }, context: ResolverContext) {
38
+ var accounting = await AccountingAPI.getAccounting(accountingId)
39
+
40
+ return await AccountingAPI.deleteItem(accounting, itemId)
41
+ }
42
+ }
@@ -0,0 +1,14 @@
1
+ import { AccountingAPI } from '../../../controllers/accounting-api'
2
+
3
+ export const queryAccountingPurchaseOrder = {
4
+ async getAccountingPurchaseOrders(_: any, { accountingId, params: ListParam }, context: ResolverContext) {
5
+ var accounting = await AccountingAPI.getAccounting(accountingId)
6
+
7
+ return await AccountingAPI.getPurchaseOrders(accounting, {
8
+ pagination: {
9
+ page: 0,
10
+ limit: 100
11
+ }
12
+ })
13
+ }
14
+ }
@@ -0,0 +1,14 @@
1
+ import { queryAccountingInvoice, mutateAccountingInvoice } from './accounting-invoice'
2
+ import { queryAccountingItem, mutateAccountingItem } from './accounting-item'
3
+ import { queryAccountingPurchaseOrder } from './accounting-purchase-order'
4
+
5
+ export const Query = {
6
+ ...queryAccountingInvoice,
7
+ ...queryAccountingItem,
8
+ ...queryAccountingPurchaseOrder
9
+ }
10
+
11
+ export const Mutation = {
12
+ ...mutateAccountingInvoice,
13
+ ...mutateAccountingItem
14
+ }
@@ -0,0 +1,5 @@
1
+ import * as Accounting from './accounting'
2
+
3
+ export const queries = [Accounting.Query] as any
4
+
5
+ export const mutations = [Accounting.Mutation]
@@ -0,0 +1,8 @@
1
+ import gql from 'graphql-tag'
2
+
3
+ export const AccountList = gql`
4
+ type AccountList {
5
+ items: [Account]
6
+ total: Int
7
+ }
8
+ `
@@ -0,0 +1,14 @@
1
+ import gql from 'graphql-tag'
2
+
3
+ export const AccountPatch = gql`
4
+ input AccountPatch {
5
+ id: String
6
+ name: String
7
+ description: String
8
+ platform: String
9
+ accountId: String
10
+ countryCode: String
11
+ trackedInventory: Boolean
12
+ cuFlag: String
13
+ }
14
+ `
@@ -0,0 +1,25 @@
1
+ import gql from 'graphql-tag'
2
+
3
+ export const Account = gql`
4
+ type Account {
5
+ id: String
6
+ name: String
7
+ domain: Domain
8
+ description: String
9
+ platform: String
10
+ accountId: String
11
+ countryCode: String
12
+ status: String
13
+ accessInfo: String
14
+ accessToken: String
15
+ refreshToken: String
16
+ trackedInventory: Boolean
17
+ expiresIn: String
18
+ tokenType: String
19
+ accountInfo: String
20
+ updater: User
21
+ creator: User
22
+ updatedAt: String
23
+ createdAt: String
24
+ }
25
+ `
@@ -0,0 +1,44 @@
1
+ import { Account } from './account'
2
+ import { NewAccount } from './new-account'
3
+ import { AccountPatch } from './account-patch'
4
+ import { AccountList } from './account-list'
5
+
6
+ export const Mutation = `
7
+ createAccount (
8
+ account: NewAccount!
9
+ ): Account
10
+
11
+ updateAccount (
12
+ id: String!
13
+ patch: AccountPatch!
14
+ ): Account
15
+
16
+ updateMultipleAccount (
17
+ patches: [AccountPatch]!
18
+ ): [Account]
19
+
20
+ deleteAccount (
21
+ id: String!
22
+ ): Boolean
23
+
24
+ deleteAccounts (
25
+ ids: [String]!
26
+ ): Boolean
27
+
28
+ refreshXeroAccessToken (
29
+ id: String!
30
+ ): Account
31
+
32
+ deactivateXeroAccount (
33
+ id: String!
34
+ ): Account
35
+ `
36
+
37
+ export const Query = `
38
+ accounts(filters: [Filter], pagination: Pagination, sortings: [Sorting]): AccountList
39
+ account(id: String!): Account
40
+
41
+ getXeroAuthURL(accounting: String!): String
42
+ `
43
+
44
+ export const Types = [Account, NewAccount, AccountPatch, AccountList]
@@ -0,0 +1,12 @@
1
+ import gql from 'graphql-tag'
2
+
3
+ export const NewAccount = gql`
4
+ input NewAccount {
5
+ name: String!
6
+ description: String
7
+ platform: String!
8
+ accountId: String
9
+ trackedInventory: Boolean
10
+ countryCode: String
11
+ }
12
+ `
@@ -0,0 +1,65 @@
1
+ import gql from 'graphql-tag'
2
+
3
+ const NewAccountInvoice = gql`
4
+ input NewAccountInvoice {
5
+ name: String!
6
+ description: String
7
+ }
8
+ `
9
+
10
+ const AccountInvoiceList = gql`
11
+ type AccountInvoiceList {
12
+ items: [AccountInvoice]
13
+ total: Int
14
+ }
15
+ `
16
+
17
+ const AccountInvoicePatch = gql`
18
+ input AccountInvoicePatch {
19
+ id: String!
20
+ name: String
21
+ description: String
22
+ cuFlag: String
23
+ }
24
+ `
25
+
26
+ const AccountInvoice = gql`
27
+ type AccountInvoice {
28
+ id: String
29
+ name: String
30
+ domain: Domain
31
+ description: String
32
+ updater: User
33
+ creator: User
34
+ updatedAt: String
35
+ createdAt: String
36
+ }
37
+ `
38
+
39
+ export const Mutation = `
40
+ createAccountInvoice(
41
+ accountingId: String!
42
+ invoice: NewAccountInvoice!
43
+ ): AccountInvoice
44
+
45
+ updateAccountInvoice(
46
+ accountingId: String!
47
+ patch: AccountInvoicePatch!
48
+ ): AccountInvoice
49
+ `
50
+
51
+ export const Query = `
52
+ getAccountInvoices(
53
+ accountingId: String!
54
+ filters: [Filter]
55
+ pagination: Pagination
56
+ sortings: [Sorting]
57
+ ): AccountInvoiceList
58
+
59
+ getAccountInvoice(
60
+ accountingId: String!
61
+ invoiceNo: String!
62
+ ): AccountInvoice
63
+ `
64
+
65
+ export const Types = [AccountInvoice, NewAccountInvoice, AccountInvoicePatch, AccountInvoiceList]
@@ -0,0 +1,64 @@
1
+ import gql from 'graphql-tag'
2
+
3
+ const NewAccountItem = gql`
4
+ input NewAccountItem {
5
+ name: String!
6
+ description: String
7
+ }
8
+ `
9
+
10
+ const AccountItemList = gql`
11
+ type AccountItemList {
12
+ items: [AccountItem]
13
+ total: Int
14
+ }
15
+ `
16
+
17
+ const AccountItemPatch = gql`
18
+ input AccountItemPatch {
19
+ id: String
20
+ name: String
21
+ description: String
22
+ cuFlag: String
23
+ }
24
+ `
25
+
26
+ const AccountItem = gql`
27
+ type AccountItem {
28
+ id: String
29
+ name: String
30
+ domain: Domain
31
+ description: String
32
+ updater: User
33
+ creator: User
34
+ updatedAt: String
35
+ createdAt: String
36
+ }
37
+ `
38
+ export const Mutation = `
39
+ createAccountItem(
40
+ accountingId: String!
41
+ item: NewAccountItem!
42
+ ): AccountItem
43
+
44
+ updateAccountItem(
45
+ accountingId: String!
46
+ patch: AccountItemPatch!
47
+ ): AccountItem
48
+ `
49
+
50
+ export const Query = `
51
+ getAccountItems(
52
+ accountingId: String!
53
+ filters: [Filter]
54
+ pagination: Pagination
55
+ sortings: [Sorting]
56
+ ): AccountItemList
57
+
58
+ getAccountItem(
59
+ accountingId: String!
60
+ itemId: String!
61
+ ): AccountItem
62
+ `
63
+
64
+ export const Types = [AccountItem, NewAccountItem, AccountItemPatch, AccountItemList]
@@ -0,0 +1,30 @@
1
+ import gql from 'graphql-tag'
2
+
3
+ const AccountPurchaseOrderList = gql`
4
+ type AccountPurchaseOrderList {
5
+ items: [AccountPurchaseOrder]
6
+ total: Int
7
+ }
8
+ `
9
+ const AccountPurchaseOrder = gql`
10
+ type AccountPurchaseOrder {
11
+ id: String
12
+ name: String
13
+ domain: Domain
14
+ description: String
15
+ updater: User
16
+ creator: User
17
+ updatedAt: String
18
+ createdAt: String
19
+ }
20
+ `
21
+ export const Query = `
22
+ getAccountPurchaseOrders(
23
+ accountingId: String!
24
+ filters: [Filter]
25
+ pagination: Pagination
26
+ sortings: [Sorting]
27
+ ): AccountPurchaseOrderList
28
+
29
+ `
30
+ export const Types = [AccountPurchaseOrder, AccountPurchaseOrderList]
@@ -0,0 +1,10 @@
1
+ import * as Accounting from './accounting'
2
+ import * as Invoice from './accounting-api/invoice'
3
+ import * as Item from './accounting-api/item'
4
+ import * as PurchaseOrder from './accounting-api/purchase-order'
5
+
6
+ export const queries = [Accounting.Query, Invoice.Query, Item.Query, PurchaseOrder.Query]
7
+
8
+ export const mutations = [Accounting.Mutation, Invoice.Mutation, Item.Mutation]
9
+
10
+ export const types = [...Accounting.Types, ...Invoice.Types, ...Item.Types, ...PurchaseOrder.Types]
@@ -0,0 +1,9 @@
1
+ export * from './entities'
2
+ export * from './migrations'
3
+ export * from './graphql'
4
+ export * from './controllers'
5
+
6
+ import './routes'
7
+ import './engine'
8
+
9
+ process.on('bootstrap-module-start' as any, async ({ app, config, client }: any) => {})
@@ -0,0 +1,9 @@
1
+ const glob = require('glob')
2
+ const path = require('path')
3
+
4
+ export var migrations = []
5
+
6
+ glob.sync(path.resolve(__dirname, '.', '**', '*.js')).forEach(function(file) {
7
+ if (file.indexOf('index.js') !== -1) return
8
+ migrations = migrations.concat(Object.values(require(path.resolve(file))) || [])
9
+ })
@@ -0,0 +1,24 @@
1
+ import Router from 'koa-router'
2
+
3
+ import { config } from '@things-factory/env'
4
+ import { getRedirectSubdomainPath } from '@things-factory/shell'
5
+
6
+ const isPathBaseDomain = !config.get('subdomain') && !config.get('useVirtualHostBasedDomain')
7
+
8
+ const debug = require('debug')('things-factory:integration-accounting:xero-router')
9
+
10
+ export const xeroPrivateRouter = new Router()
11
+
12
+ xeroPrivateRouter.get(`${isPathBaseDomain ? '/domain/:domain' : ''}/callback-private-xero`, async (context, next) => {
13
+ const { domain } = context.state
14
+
15
+ const xeroAccountingCookies = context.cookies.get('xero-accounting')
16
+ const { id, status, message } = JSON.parse(xeroAccountingCookies)
17
+
18
+ context.redirect(
19
+ `${getRedirectSubdomainPath(
20
+ context,
21
+ domain.subdomain
22
+ )}account-xero/${id}/connect-callback?status=${status}&message=${message}`
23
+ )
24
+ })