|
| 1 | +import * as CR from 'typings' |
| 2 | +import * as G from 'typings/graphql' |
| 3 | +import { assign, ActionFunctionMap } from 'xstate' |
| 4 | +import client from '../../apollo' |
| 5 | +import { setAuthToken } from '../../apollo/auth' |
| 6 | +import authenticateMutation from '../../apollo/mutations/authenticate' |
| 7 | +import channel from '../../channel' |
| 8 | +import onError from '../../../services/sentry/onError' |
| 9 | +import { MachineContext, MachineEvent } from './index' |
| 10 | + |
| 11 | +interface AuthenticateData { |
| 12 | + editorLogin: { |
| 13 | + token: string |
| 14 | + user: G.User |
| 15 | + } |
| 16 | +} |
| 17 | + |
| 18 | +interface AuthenticateVariables { |
| 19 | + machineId: string |
| 20 | + sessionId: string |
| 21 | + editor: 'VSCODE' |
| 22 | +} |
| 23 | + |
| 24 | +const actions: ActionFunctionMap<MachineContext, MachineEvent> = { |
| 25 | + setEnv: assign({ |
| 26 | + env: (context: CR.MachineContext, event: CR.MachineEvent) => { |
| 27 | + return { |
| 28 | + ...context.env, |
| 29 | + ...event.payload.env, |
| 30 | + } |
| 31 | + }, |
| 32 | + }), |
| 33 | + authenticate: async (context: CR.MachineContext): Promise<void> => { |
| 34 | + const result = await client |
| 35 | + .mutate<AuthenticateData, AuthenticateVariables>({ |
| 36 | + mutation: authenticateMutation, |
| 37 | + variables: { |
| 38 | + machineId: context.env.machineId, |
| 39 | + sessionId: context.env.sessionId, |
| 40 | + editor: 'VSCODE', |
| 41 | + }, |
| 42 | + }) |
| 43 | + .catch(error => { |
| 44 | + onError(error) |
| 45 | + console.log('ERROR: Authentication failed') |
| 46 | + console.log(error.message) |
| 47 | + let message |
| 48 | + if (error.message.match(/Network error:/)) { |
| 49 | + message = { |
| 50 | + title: 'Network Error', |
| 51 | + description: 'Make sure you have an Internet connection. Restart and try again', |
| 52 | + } |
| 53 | + } else { |
| 54 | + message = { |
| 55 | + title: 'Server Error', |
| 56 | + description: error.message, |
| 57 | + } |
| 58 | + } |
| 59 | + channel.receive({ data: { type: 'ERROR', payload: { error: message } } }) |
| 60 | + return |
| 61 | + }) |
| 62 | + |
| 63 | + if (!result || !result.data) { |
| 64 | + const error = new Error('Authentication request responded with no data') |
| 65 | + console.log(error) |
| 66 | + onError(error) |
| 67 | + return |
| 68 | + } |
| 69 | + const { token } = result.data.editorLogin |
| 70 | + // add token to headers |
| 71 | + setAuthToken(token) |
| 72 | + // pass authenticated action back to state machine |
| 73 | + channel.receive({ data: { type: 'AUTHENTICATED' } }) |
| 74 | + }, |
| 75 | +} |
| 76 | + |
| 77 | +export default actions |
0 commit comments