UNPKG

@alore/auth-react-native-ui

Version:
809 lines (748 loc) 34.3 kB
import { AloreAuthError } from '@alore/auth-react-native-sdk/src/AloreAuthError'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { Passkey } from 'react-native-passkey'; import { assign, createMachine, DoneInvokeEvent, interpret, State } from 'xstate'; import { AuthMachineContext, AuthMachineEvents, AuthMachineServices } from './types'; const initialContext: AuthMachineContext = { locale: 'en', authMethods: { google: false, passkey: false, password: false, }, }; export const authMachine = createMachine( { /** #no-spell-check @xstate-layout N4IgpgJg5mDOIC5QEMCuAXAFgWWQY0wEsA7MAYgCUBRAZSoBUB9AYQHkA5eqgDXoG0ADAF1EoAA4B7WIXSEJxUSAAeiACwAmADQgAnogCc+gHQCAzAHZzANgCsA-ao03TARgC+b7Wiy4CJMEYk+LIAbuQAkuzh9OEAggAy4QBaVIIiSCCS0rLyiioI6qrmRoUCABzqpvrqAi6mVTbaegXq6kb6AkX6FuY2+lbW6h5eGDj4RKRGwYRhgcQyhMgANkZhAE6EAGY6sUsSa2A06MjoqLBkEPIBJCESANYB3mN+k9OzJAvLq2Ab27v7h2Op1gCBuEjwJzkxDSaUUWQWuQy+RcAjMRnMLlUphsFRc5nULgqTUQtjK7Vq+jsWNMZRx5mGICevgmjzwoWu81kX3WWx2ewORxOZzIPzW+yMYiWJ02+wAtlNRsz-FM2TMOZ8Vjy-vzAUKQWCITlocJYRl4Ua8ogUZ0jDTVA4bHUrGUyvViQhHVYSnj6vo6jTqkNPIzFeNlW91VyVoQIEtyPFWABxSKMGhcAAKpvEUgRCiRVtMAyMZX0rtUzoqAnUvXdHRsRkcmMchmsqhcVgZTLDr1V705i2jsfIadiFCY6diNBoAGkqABNRgJ5PsLOZHMW-MIFx44wCcxFH3WGyqASNXRWqvGV1WVQ2cyU0sVfSd0MvVnsuYawJDyhUZNpqgKFTDNV3NKFLQQDFTGLQxKVMcoqiqd1t2dIxnVRHFy36KsbBfHxu3fNVPyjb841-f8uCAgDMxcdJs2ycDNzKOoYMMTCalvDFkMqMl9HMCorD3dQBm3Mo8OeFkVQ-D4SJjMjqAowDgKoTN1DotcGMRUB8j9YwUQqMpyxsdQ+gsZD4PrSlzFMYS7w0exxKVHsPz2KASCMMBZWQQgliOMAxDIAAhWJmGnUD10Y7TEEdAk0NUQzChcYyrCsUx3VpXd7w4lEqisQpHIIqSiNc9zPO83z0H8sgADEGGYAAJVMEn4YQ4QirTlCtP16wsVpnCSv1DPSl10SsbpKhMlKT1w4MuzfIrZhK4gPK8ny-ICkcx0YCcp1nBcl0icLNLzKKCmsXc70JdRXVaAkymQ9toLbAl234jEbFSgr5ojIwlqMA50A2MAQhIKAaGWdALiuOZbgeBV8O+3sAj+gGgZB4gwYh0FiFuQ0oRhVqzXak7Oq3OtbXxEzXD6QlVAekzi06ctzBwvLn1m19JJ+lGwEBwhgdB8Glkh0VxUlaU5XhiTwyR36JDc5bUf59HMeF7HccheQCfUsCOuRbqKb66nBrp88tzMJ7jN01xtxPekOYRrnZb+sRkFgWAAHd9ggdagpCsLCfo3MIJM9tbSsFw-RvZ1Szy7ibT9Ez1A6AQI7MMSHel5zivl9zXfdr21h9yqAoANUA8Jqv2pNDsDjTg83SOqwbBwMUS-FHDSs2XDuowksEzF91qPFVC+p2XNz5atR0UH4knqHJjBOG5vHnOFe+X4Z4xueFfV8FNeNIQjob06m7ae0D3bwosWQx0XGLNtelMRwiiKDtM6cwjFsnjfeVn+fRZrAlFKdAMo1jyhXjLCe69p7-13gaA+2s2rHQgpHHuLdL6P2vl3Zo-oyQfT6hlG8lIgwjEdlAtepVVpLHUJsZAv46DsAACIsFYEw1IdddYk3yK0E8xYyiohsk2eolhkIpWKA4Esdg9wtkJGPCh3915lR8rQ+h5cKCVwXFQbAsRwjxEYOoaqsRj4blOrdAQ-DBEEk7j0ZCzELHbmTrSOw+Ikqjw-oVbmP9lE0LoX7UKJjIqkz6hYl0VjhG2O7vFCxPEzCFGcNZdmZCs5f2Rj-WBGMqDUNUQvDksNHicwUWkmBPw-6ZOyXQveeMtYmk4cTCCjpXBxQSm2ZKqVawYhMKnYS11CyGVPPI7Oij3IZKgFk8qOTAHAIluAqWn8FrFJGaU7YoNxkqMqQgo0SCiYoM3K0eCli4kRNEd3DExRrCYh6NUfE9tknzK8evA4sAwDEAgKs6hzAJAQHIJcReON7gFPIUMxZis4AvLeeU8qnzvlVMQbUnW9S9kmVCQIo5NiTm4LvPWPoQ9Ki2HitiQZqS5br3zrAB4Oh1pGFgMcNYkNfl5IBXMzxzsf5kopVSmlyA6Wwq2fC5BJ9gmCIbIZCOLMbyOlPO6DiqgSg4jKEPAR1pbkhiBcSl2btyVgEpSXaltKRZrDFEA8WoDJaQOBSSvOmqOW6q5TyzZ+N+U7MFfkGK98bwtKSsJdp3cFX1kEn6KsAj7wBqJQsy1y12XaqpXJcgABVOgQFIjpjjeOScM55yLhriuOpuyzHJ2MK0AY95eh5VcNK1OXog12GkZHPiM07ksugVa92Nr-JGDOD8cIxAxAYFyTDJl5r1VsutdG3Vna1jdt7egXljqj65pdYga6zF0R7kufxQkNYzYEkEkYGwdJjz7kLM6BtqqUnho1a2sd7aJ1Tr7VMk1YCIGFItZerVOqb3PMnT2jAs6anzoRXm0mbrmkaFad6nBXUizYVsKeXh9pSFnvuay0lo6P1iA7V+u96AaCoDwHgOA5xqqRHCDQRqO0M3V2XIEvWiAbLVDQo01EzEygnorfedEzZ+jYgGBWMNDyW3vqpVGnQFA4CoGFv2pegLz0CcjWh4TaGxOwAkzOh1-6aPcOij3d18UwNepSpBgoXq0KpX3H0R0Gh36NsRs2+TV70MSiU+JyTD6QFPuZbZyh9mhO6pE8p1Tf7D6aYaXUXTnq2lGZqLu1wBJSx4u6L0fjssDhuRpT8Fa5VfbBQCQu0xpNSToldB0Vw5YND7mlS4vdhQbKlefiZZLH5UuEHS0Anxvt2A8BaoBxdZMGP2ipL0FmrYtBmyxLUYsNJ+LlgjhfRrRFmutcy2tEuZBEysCTPEKgWbqN5aCfra6aFygnjxTihw7pbyFHDrSTErGBiOnm7MRblU2vUN9owlhClSP0AoLEGIHBGDaN0fEELjdrBklcFWOLjjDJnmaHbYw+7n5VhpFbJKj2AjPYyxO4gyBZSAiqjlgOPX8s8NPMUYSUF2yR3qxdpKZIDKVHKxHMaGP-pgDSy9zDPxcf4-e1QZhjAvtpl+-99ggOdF6NB2Y1wEjtzjTYrUYSF3ahemMgq1jzFCjdTZ1joBOO8cE42gLz7f5vui-CADoHUvaICtJ0umk0FnBjULPaDEOF3SFn4iUNixX92nkpLrjnLWufPNee88qUn-nLxfcSvX1LwUR58kF7ZQd7dbhY8WZOthCTGWcI4T3KV6wB-6NZE7QfOcZbDxCsZ1CRSGrFu5s1sfw3x+r0npYKenVp-21aCzDZzrdPqHE8wnuwloUMtx962IM42dXk94PS2fGl2WDGA+vt1GaIl8D6XpMm7QRLPFVxV0kJm3qPFEop4FWFHsdUCvIeMvL9XxAdfq2ie754b3F0N0cQOA6IST3D6YvasVjVofoOwdwDxLzBfSvV7cqFfJYNfI0X2agD7VhdhD-K0FmNoVKCoD6d6FKZiQA4SckGkAYU8Y9LEe-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-2LGsGslSmfhPD3FocE0aOwaVtuM-qvBvDbHbGEjxFpHjllUcBqygk4jqBEanmcO3knmYewOgZZnYf4YQe7hqDJHtFRDxDbn7r-JLLs2W18WQBwZqHxD7jGkxGSmThvm7jsGkY3RjPqx7k0Z3o71UWcY0DJH2VdFRCfMjmQnxGglRF6Hpx7nEPwrse8w5LpMUJ8mhQbokZDnsj3WPDK0MEERSlvgEX6uMjxu3GJOCZCr0dinrWPEji6BQjsW6HaAGueJPHimdAaYmrtXQD0bGk-MDracbPbArUO1TldHbFLAJMLEGeWrfoKaRRYgLVEjrW6ulXl2LCALZi6FlxWeuu5zsowGccEgsXuNSnsBaai06DaGuiP23HuemlOdqvOewwioI3dhwchxPrTlLGeP3Gme3RkXJBvHxANvvFvE+evTqoczWoBecAZxdFaFxGJIdKXVPDV1qHLHqFpH3HSbtuqsWOYdi3aD4lFOxEMFvGlTYgHwEVwMMlcA3oycWqXywf8mYZSndpJedArDGnnrUBAJMANqjm6H3Qzs5ZYJ8INz53EZrMkZqBiWtBv24ribG0qERy7NosIJsn+M5JyaWGYcnxMGXN6itOMk90bMeP7qiOcHq3+Kf0QJf2QOVZatuMJFY2uwVTVpHldEAKaV4UlVqHxBdH+K0J8nNb9f6eHmEJ+rhzozVsZmNvsA+KurEd5fWdOngmsFXRRBfjvGPS4epFSr7up2PCrH+MBJOORO5PyzvM3B4wsTwasxpCDTxAuxpHPl5rggJP3H+P1Jr19NROIDoMpdjKPDOpMg0HVs9wsbcdQssH4nmezNDPDLWGcfbEiccU4efjxPLfinPjiwVSqGi1lbJa5a50abzb3xSmMFbspB+usnMwu0pnRBRAScrtsCuq+eGb0bxFtA6FfaPwsAZdYomy8ZMhKefkDyfqsqWrObWZVZDlskBpxFsBqH3X4iMwsc+r3BFdqxFYA8Re+ZEquddHYq-P3UkWqCypo-gi+J3P3HvHI8cxMvCrwz+fgAffyBxvrAEVKDMF-MJM0v6z0oxv0kKqQ-JaIomtKoapGYE7oyLobGmIEQQ1FSyrGfKDFWYmfjylJdZOQ8U+Wtur45wcfgZ2SerHXdRA0rUAVWKDbrnszYEPBsIEhsgBhpwZrbaGmPsFizIaMzKfLpKZDTMAVKHvmKzpmCdq-QC7GhyvXqSmsm6RTYQFxG6cn0JFRtyjDUAUPvQAkDEATpINEmPD9UoZ-e0DjE2FU+13DjGnKD4hLEM1bIACMJB0AyvZQl175frbxUmTD7DtANgoBMBVPCxn2n32v+J+hUpWyPYYwsArQahtBMAwAfOZuXPtAeF7RWuOgSwluuudaqvc8j9jwaQf3Q63AgA */ id: 'authMachine', predictableActionArguments: true, tsTypes: {} as import('./index.typegen').Typegen0, schema: { context: {} as AuthMachineContext, services: {} as AuthMachineServices, events: {} as AuthMachineEvents, }, states: { inactive: { entry: [ assign({ sessionUser: () => undefined, CCRPublicKey: () => undefined, error: () => undefined, googleOtpCode: () => undefined, googleUser: () => undefined, RCRPublicKey: () => undefined, salt: () => undefined, sessionId: () => undefined, userEmail: () => undefined, passkeyLoginResult: () => undefined, passkeyRegistrationResult: () => undefined, registerUser: () => undefined, }), () => AsyncStorage.removeItem('authState'), ], on: { INITIALIZE: { target: 'active', }, }, }, active: { states: { initial: { states: { verifyAloreStatus: { invoke: { src: 'healthCheck', onDone: { target: 'idle', actions: 'resetError', }, onError: { target: '#authMachine.error', actions: 'assignError', }, }, }, idle: { on: { LOGIN_STEP: '#authMachine.active.login', START_PASSKEY_LOGIN: '#authMachine.active.login.passkeyStep', REGISTER_STEP: [ { target: '#authMachine.active.register', cond: 'requireEmailVerification', }, { target: '#authMachine.active.register.usernameStep', cond: 'requireUsername', }, '#authMachine.active.register.passkeyStep.idle', ], }, }, }, entry: assign({ sessionUser: () => undefined, CCRPublicKey: () => undefined, googleOtpCode: () => undefined, googleUser: () => undefined, RCRPublicKey: () => undefined, salt: () => undefined, sessionId: () => undefined, userEmail: () => undefined, passkeyLoginResult: () => undefined, passkeyRegistrationResult: () => undefined, registerUser: () => undefined, }), initial: 'verifyAloreStatus', }, login: { states: { emailStep: { on: { BACK: { target: '#authMachine.active.initial' }, FETCH_SALT: { target: '#authMachine.active.login.retrievingSalt', actions: assign({ googleOtpCode: () => undefined, googleUser: () => undefined, registerUser: () => undefined, sessionId: () => undefined, }), }, START_PASSKEY_LOGIN: { target: '#authMachine.active.login.passkeyStep', }, }, exit: 'resetError', }, retrievingSalt: { invoke: { src: 'retrieveSalt', onDone: { target: '#authMachine.active.login.passwordStep', actions: assign({ salt: (_context, event) => event.data, error: () => undefined, }), }, onError: { target: '#authMachine.active.login.emailStep', actions: 'assignError', }, }, entry: 'resetError', }, passwordStep: { on: { BACK: { target: '#authMachine.active.login.emailStep', actions: assign({ googleUser: () => undefined, registerUser: () => undefined, error: () => undefined, }), }, VERIFY_LOGIN: '#authMachine.active.login.verifyingLogin', }, exit: 'resetError', }, verifyingLogin: { invoke: { src: 'verifyLogin', onDone: [ { target: 'email2fa', actions: assign({ sessionId: (_, event) => event.data.sessionId, error: () => undefined, }), }, ], onError: { target: '#authMachine.active.login.passwordStep', actions: 'assignError', }, }, entry: 'resetError', }, email2fa: { on: { RESEND_CODE: '#authMachine.active.login.resendingEmailCode', VERIFY_EMAIL_2FA: '#authMachine.active.login.verifyingEmail2fa', BACK: { target: '#authMachine.active.login.passwordStep', actions: 'resetError', }, }, exit: 'resetError', }, verifyingEmail2fa: { invoke: { src: 'verifyEmail2fa', onError: { target: '#authMachine.active.login.email2fa', actions: 'assignError', }, onDone: { target: '#authMachine.active.signedOn', actions: assign({ sessionUser: (_, event) => event.data, error: () => undefined, }), }, }, entry: 'resetError', }, resendingEmailCode: { invoke: { src: 'verifyLogin', onDone: { target: '#authMachine.active.login.email2fa', actions: assign({ sessionId: (_, event) => event.data.sessionId, error: () => undefined, }), }, }, entry: 'resetError', }, passkeyStep: { states: { start: { invoke: { src: 'startPasskeyAuth', onDone: { target: '#authMachine.active.login.passkeyStep.idle', actions: assign({ RCRPublicKey: (_context, event) => event.data.requestChallengeResponse, sessionId: (_, event) => event.data.sessionId, error: () => undefined, }), }, onError: { target: '#authMachine.active.initial', actions: 'assignError', }, }, }, idle: { on: { USER_INPUT_PASSKEY_LOGIN: '#authMachine.active.login.passkeyStep.userInput', }, }, userInput: { invoke: { src: 'userInputLoginPasskey', onDone: { target: '#authMachine.active.login.passkeyStep.userInputSuccess', actions: assign({ passkeyLoginResult: (_context, event) => event.data, error: () => undefined, }), }, onError: { target: '#authMachine.active.initial', actions: 'assignError', }, }, }, userInputSuccess: { on: { FINISH_PASSKEY_LOGIN: '#authMachine.active.login.passkeyStep.passkeyResult', }, }, passkeyResult: { invoke: { src: 'finishPasskeyAuth', onDone: { target: '#authMachine.active.signedOn', actions: assign({ sessionUser: (_context, event) => event.data, error: () => undefined, }), }, onError: { target: '#authMachine.active.initial.idle', actions: 'assignError', }, }, }, }, exit: assign({ CCRPublicKey: () => undefined, passkeyLoginResult: () => undefined, passkeyRegistrationResult: () => undefined, RCRPublicKey: () => undefined, }), initial: 'start', }, }, initial: 'emailStep', }, register: { states: { emailStep: { on: { BACK: '#authMachine.active.initial.idle', NEXT: '#authMachine.active.register.usernameStep', GOOGLE_LOGIN: { target: '#authMachine.active.register.googleRegister', }, SEND_REGISTRATION_EMAIL: 'sendingEmail', }, exit: 'resetError', }, usernameStep: { on: { BACK: { target: '#authMachine.active.register.emailStep' }, SEND_REGISTRATION_EMAIL: [ { target: '#authMachine.active.register.sendingEmail', cond: 'requireEmailVerification', }, 'passwordStep', ], }, exit: 'resetError', }, sendingEmail: { invoke: { src: 'sendConfirmationEmail', onDone: { target: '#authMachine.active.register.emailValidationStep', actions: assign({ salt: (_context, event) => event.data?.salt, sessionId: (_context, event) => event.data?.sessionId, error: () => undefined, }), }, onError: { target: 'emailStep', actions: 'assignError', }, }, entry: assign({ error: () => undefined, sessionId: () => undefined, }), }, emailValidationStep: { on: { VERIFY_EMAIL: 'verifyingEmail', BACK: { target: '#authMachine.active.register.usernameStep', actions: 'resetError', }, RESEND_CODE: '#authMachine.active.register.resendingRegistrationEmail', }, exit: 'resetError', }, verifyingEmail: { invoke: { src: 'verifyEmail', onDone: [ { target: '#authMachine.active.register.passkeyStep.idle', actions: 'resetError', cond: 'isPasskeyMethod', }, { target: '#authMachine.active.register.passwordStep', actions: 'resetError', }, ], onError: { target: '#authMachine.active.register.emailValidationStep', actions: 'assignError', }, }, entry: 'resetError', }, passwordStep: { on: { BACK: { target: '#authMachine.active.register.usernameStep', }, COMPLETE_REGISTRATION: '#authMachine.active.register.completingRegistration', }, exit: 'resetError', }, completingRegistration: { invoke: { src: 'completeRegistration', onDone: { target: '#authMachine.active.signedOn', actions: assign({ sessionUser: (_, event) => event.data, error: () => undefined, }), }, onError: { target: '#authMachine.active.register.passwordStep', actions: 'assignError', }, }, entry: 'resetError', }, resendingRegistrationEmail: { invoke: { src: 'sendConfirmationEmail', onDone: { target: '#authMachine.active.register.emailValidationStep', actions: assign({ salt: (_context, event) => event.data?.salt, sessionId: (_context, event) => event.data?.sessionId, error: () => undefined, }), }, onError: { target: '#authMachine.active.register.emailValidationStep', actions: 'assignError', }, }, entry: assign({ error: () => undefined, sessionId: () => undefined, }), }, // TODO: add google register googleRegister: { invoke: { src: 'googleLogin', onDone: [ { target: '#authMachine.active.register.passwordStep', actions: assign({ registerUser: (_, event) => event.data?.registerUser, }), cond: 'isNewUser', }, // { // target: 'idle', // actions: assign({ // googleOtpCode: (_, event) => event.data.googleOtpCode, // salt: (_, event) => event.data.salt, // googleUser: (_, event) => event.data.googleUser, // }), // }, ], onError: { target: '#authMachine.active.register.usernameStep', actions: 'assignError', }, }, entry: assign({ googleUser: () => undefined, registerUser: () => undefined, }), }, passkeyStep: { states: { start: { invoke: { src: 'startRegisterPasskey', onDone: { target: '#authMachine.active.register.passkeyStep.idle', actions: assign({ CCRPublicKey: (_context, event) => event.data.ccr, sessionId: (_, event) => event.data.sessionId, userId: (_, event) => event.data.userId, error: () => undefined, }), }, onError: { target: '#authMachine.active.initial.idle', actions: 'assignError', }, }, }, idle: { on: { USER_INPUT_PASSKEY_REGISTER: '#authMachine.active.register.passkeyStep.userInput', START_PASSKEY_REGISTER: { target: '#authMachine.active.register.passkeyStep.start', }, }, }, userInput: { invoke: { src: 'userInputRegisterPasskey', onDone: { target: '#authMachine.active.register.passkeyStep.userInputSuccess', actions: assign({ passkeyRegistrationResult: (_context, event) => event.data, error: () => undefined, }), }, onError: { target: '#authMachine.active.initial.idle', actions: 'assignError', }, }, }, userInputSuccess: { on: { FINISH_PASSKEY_REGISTER: '#authMachine.active.register.passkeyStep.passkeyResult', }, }, passkeyResult: { invoke: { src: 'finishRegisterPasskey', onDone: { target: '#authMachine.active.register.passkeyStep.success', actions: 'resetError', }, onError: { target: '#authMachine.active.initial.idle', actions: 'assignError', }, }, }, success: { type: 'final', on: { START_PASSKEY_LOGIN: { target: '#authMachine.active.login.passkeyStep', actions: assign({ userEmail: (context, event) => event.payload ? event.payload.email : context.userEmail, isFirstLogin: () => true, }), }, }, }, }, exit: assign({ error: () => undefined, CCRPublicKey: () => undefined, passkeyLoginResult: () => undefined, passkeyRegistrationResult: () => undefined, RCRPublicKey: () => undefined, }), initial: 'start', }, }, initial: 'emailStep', }, signedOn: { type: 'final', entry: assign({ googleUser: () => undefined, registerUser: () => undefined, CCRPublicKey: () => undefined, RCRPublicKey: () => undefined, error: () => undefined, googleOtpCode: () => undefined, passkeyRegistrationResult: () => undefined, salt: () => undefined, userEmail: () => undefined, passkeyLoginResult: () => undefined, sessionId: () => undefined, }), on: { LOGOUT: { target: '#authMachine.inactive', actions: assign({ sessionUser: () => undefined, CCRPublicKey: () => undefined, error: () => undefined, googleOtpCode: () => undefined, googleUser: () => undefined, RCRPublicKey: () => undefined, salt: () => undefined, sessionId: () => undefined, userEmail: () => undefined, passkeyLoginResult: () => undefined, passkeyRegistrationResult: () => undefined, registerUser: () => undefined, }), }, INACTIVATE_USER: 'inactivatingUser', }, }, inactivatingUser: { invoke: { src: 'inactivateUser', onDone: { target: '#authMachine.inactive', actions: assign({ sessionUser: () => undefined, CCRPublicKey: () => undefined, error: () => undefined, googleOtpCode: () => undefined, googleUser: () => undefined, RCRPublicKey: () => undefined, salt: () => undefined, sessionId: () => undefined, userEmail: () => undefined, passkeyLoginResult: () => undefined, passkeyRegistrationResult: () => undefined, registerUser: () => undefined, }), }, onError: { target: '#authMachine.active.signedOn', actions: 'assignError', }, }, }, }, initial: 'initial', }, error: {}, }, initial: 'inactive', on: { RESET_CONTEXT: { target: '#authMachine.inactive', actions: assign({ sessionUser: () => undefined, CCRPublicKey: () => undefined, error: () => undefined, googleOtpCode: () => undefined, googleUser: () => undefined, RCRPublicKey: () => undefined, salt: () => undefined, sessionId: () => undefined, userEmail: () => undefined, passkeyLoginResult: () => undefined, passkeyRegistrationResult: () => undefined, registerUser: () => undefined, }), }, }, }, { services: { healthCheck: async (_context, _event) => { throw new Error('Not implemented'); }, startPasskeyAuth: async (_context, _event) => { throw new Error('Not implemented'); }, userInputLoginPasskey: async (_context, _event) => { throw new Error('Not implemented'); }, finishPasskeyAuth: async (_context, _event) => { throw new Error('Not implemented'); }, completeRegistration: async (_context, _event) => { throw new Error('Not implemented'); }, sendConfirmationEmail: async (_context, _event) => { throw new Error('Not implemented'); }, startRegisterPasskey: async (_context, _event) => { throw new Error('Not implemented'); }, retrieveSalt: async (_context, _event) => { throw new Error('Not implemented'); }, finishRegisterPasskey: async (_context, _event) => { throw new Error('Not implemented'); }, userInputRegisterPasskey: async (_context, _event) => { throw new Error('Not implemented'); }, googleLogin: async (_context, _event) => { throw new Error('Not implemented'); }, verifyEmail: async (_context, _event) => { throw new Error('Not implemented'); }, verifyLogin: async (_context, _event) => { throw new Error('Not implemented'); }, verifyEmail2fa: async (_context, _event) => { throw new Error('Not implemented'); }, inactivateUser: async (_context, _event) => { throw new Error('Not implemented'); }, }, guards: {}, actions: {}, }, ); export const getResolvedState = async () => { const state = await AsyncStorage.getItem('authState'); let resolvedState; if (state) { const stateDefinition = JSON.parse(state); const previousState = State.create(stateDefinition); // @ts-ignore resolvedState = authMachine.resolveState(previousState); } return resolvedState; }; export const authService = ( services: {}, context: AuthMachineContext, resolvedState?: Awaited<ReturnType<typeof getResolvedState>>, ) => { const mergedContext = { ...authMachine.context, ...initialContext, ...context, }; return interpret( authMachine.withConfig( { services, guards: { // @ts-ignore isNewUser: (_, event) => !!event.data.isNewUser, // @ts-ignore isPasskeyMethod: (context, _) => !!context.authProviderConfigs?.enablePasskeys && Passkey.isSupported(), requireEmailVerification: (context, _) => { return !!context.authProviderConfigs?.requireEmailVerification; }, requireUsername: (context, _) => { return !!context.authProviderConfigs?.requireUsername; }, }, actions: { resetError: assign((_, event) => { return { error: undefined }; }), assignError: assign((_, event) => { const { data: rawError } = event as DoneInvokeEvent<any>; if (!rawError) { return { error: { type: 'UNKNOWN_ERROR', message: 'No data found' } }; } if (rawError instanceof AloreAuthError) { return { error: { type: rawError.type, message: rawError.message, }, }; } return { error: { type: 'UNKNOWN_ERROR', message: rawError?.error || rawError?.message || rawError?.data || (typeof rawError === 'string' ? rawError : 'Unknown error'), }, }; }), }, }, mergedContext, ), ) .onTransition(async (state) => { if (state.changed && state.matches('active.signedOn')) { await AsyncStorage.setItem('authState', JSON.stringify(state)); } }) .start(resolvedState); };