Skip to content

WIP - Split state machines #83

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from
Prev Previous commit
Next Next commit
create authenticate machine
  • Loading branch information
ShMcK committed Jan 26, 2020
commit b437f26ec5f27f6e3a73333d08efc55ac6864459
77 changes: 77 additions & 0 deletions web-app/src/services/state/authenticate/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import * as CR from 'typings'
import * as G from 'typings/graphql'
import { assign, ActionFunctionMap } from 'xstate'
import client from '../../apollo'
import { setAuthToken } from '../../apollo/auth'
import authenticateMutation from '../../apollo/mutations/authenticate'
import channel from '../../channel'
import onError from '../../../services/sentry/onError'
import { MachineContext, MachineEvent } from './index'

interface AuthenticateData {
editorLogin: {
token: string
user: G.User
}
}

interface AuthenticateVariables {
machineId: string
sessionId: string
editor: 'VSCODE'
}

const actions: ActionFunctionMap<MachineContext, MachineEvent> = {
setEnv: assign({
env: (context: CR.MachineContext, event: CR.MachineEvent) => {
return {
...context.env,
...event.payload.env,
}
},
}),
authenticate: async (context: CR.MachineContext): Promise<void> => {
const result = await client
.mutate<AuthenticateData, AuthenticateVariables>({
mutation: authenticateMutation,
variables: {
machineId: context.env.machineId,
sessionId: context.env.sessionId,
editor: 'VSCODE',
},
})
.catch(error => {
onError(error)
console.log('ERROR: Authentication failed')
console.log(error.message)
let message
if (error.message.match(/Network error:/)) {
message = {
title: 'Network Error',
description: 'Make sure you have an Internet connection. Restart and try again',
}
} else {
message = {
title: 'Server Error',
description: error.message,
}
}
channel.receive({ data: { type: 'ERROR', payload: { error: message } } })
return
})

if (!result || !result.data) {
const error = new Error('Authentication request responded with no data')
console.log(error)
onError(error)
return
}
const { token } = result.data.editorLogin
// add token to headers
setAuthToken(token)
// pass authenticated action back to state machine
channel.receive({ data: { type: 'AUTHENTICATED' } })
},
}

export default actions
61 changes: 61 additions & 0 deletions web-app/src/services/state/authenticate/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import * as CR from 'typings'
import { Machine } from 'xstate'
import actions from './actions'

export type MachineEvent =
| { type: 'ENV_LOAD'; payload: { env: CR.Environment } }
| { type: 'AUTHENTICATED' }
| { type: 'ERROR'; payload: { error: Error } }

export type StateSchema = {
states: {
LoadEnvironment: {}
Authenticate: {}
Authenticated: {}
}
}

export type MachineContext = {
env: CR.Environment
error: CR.ErrorMessage | null
}

const options = {
actions,
}

export const authenticateMachine = Machine<MachineContext, StateSchema, MachineEvent>(
{
id: 'authenticate',
context: {
error: null,
env: { machineId: '', sessionId: '', token: '' },
},
initial: 'LoadEnvironment',
states: {
LoadEnvironment: {
onEntry: ['loadEnv'],
on: {
ENV_LOAD: {
target: 'Authenticate',
actions: ['setEnv'],
},
},
},

Authenticate: {
onEntry: ['authenticate'],
on: {
AUTHENTICATED: 'Authenticated',
ERROR: {
actions: ['setError'],
},
},
},
Authenticated: {
type: 'final',
},
},
},
options,
)