import { getAuthDetails } from './api' import type { AllauthResponse, AuthenticationMethod } from './types' export const AuthChangeEvent = { LOGGED_OUT: 'LOGGED_OUT', LOGGED_IN: 'LOGGED_IN', REAUTHENTICATED: 'REAUTHENTICATED', REAUTHENTICATION_REQUIRED: 'REAUTHENTICATION_REQUIRED', FLOW_UPDATED: 'FLOW_UPDATED' } export default function getAuthChangeEvent(fromAuth: AllauthResponse, toAuth: AllauthResponse): string { let before = getAuthDetails(fromAuth) const after = getAuthDetails(toAuth) if (toAuth.status === 410) { return AuthChangeEvent.LOGGED_OUT } const shouldReauth = () => { const fromMethods = (fromAuth.data?.methods as AuthenticationMethod[] | undefined) ?? [] const toMethods = (toAuth.data?.methods as AuthenticationMethod[] | undefined) ?? [] return (before.requiresReauthentication) || (fromMethods.length < toMethods.length) } // Corner case: user ID change. Treat as if we're transitioning from anonymous state. if (before.user && after.user && before.user?.id !== after.user?.id) { before = { isAuthenticated: false, requiresReauthentication: false, user: null, pendingFlow: undefined } } if (!before.isAuthenticated && after.isAuthenticated) { return AuthChangeEvent.LOGGED_IN } else if (before.isAuthenticated && !after.isAuthenticated) { return AuthChangeEvent.LOGGED_OUT } else if (before.isAuthenticated && after.isAuthenticated) { if (after.requiresReauthentication) { return AuthChangeEvent.REAUTHENTICATION_REQUIRED } else if (shouldReauth()) { return AuthChangeEvent.REAUTHENTICATED } } else if (!before.isAuthenticated && !after.isAuthenticated) { const fromFlow = before.pendingFlow const toFlow = after.pendingFlow if (toFlow?.id && fromFlow?.id !== toFlow.id) { return AuthChangeEvent.FLOW_UPDATED } } // No change. return '' }