UNPKG

react-native-gigya-sdk

Version:
296 lines (257 loc) 7.75 kB
import { GigyaSdkErrors, GigyaSdkStateType, GigyaSdkErrorType, GigyaSdkErrorCodes, GigyaSdkAccountInfoType, GigyaSdkConflictingAccountType, GigyaSdkRegisteredAccountType, } from '../types' import getState from './getState' import setSession from './setSession' import isGigyaError from './isGigyaError' import getAccountInfo from './getAccountInfo' import finalizeRegistration from './finalizeRegistration' import acceptConsentSchemas from './acceptConsentSchemas' import clearErrorState from '../internals/clearErrorState' import getConflictingAccount from './getConflictingAccount' import resendVerificationEmail from './resendVerificationEmail' import getUnacceptedConsentSchemas from './getUnacceptedConsentSchemas' import saveAuthenticationAttempt from '../internals/saveAuthenticationAttempt' type ProviderType = Exclude< Exclude<GigyaSdkStateType['authenticationAttempt'], undefined>['type'], undefined > type OptionsType = { error?: GigyaSdkErrorType noSetSession?: boolean noFinalize?: boolean isRegistration?: boolean } type ActionRequiredType = | { type: 'emailVerification' } | { type: 'acceptToS' callback: () => Promise<InternalOutputType> } | { type: 'conflictingAccount' loginId?: GigyaSdkConflictingAccountType['loginID'] loginProviders?: GigyaSdkConflictingAccountType['loginProviders'] } type InternalOutputType = | { handled: false error: GigyaSdkErrorType | undefined } | { handled: true account: GigyaSdkAccountInfoType | GigyaSdkRegisteredAccountType } | { handled: true regTokenExpired: true error: GigyaSdkErrorType | undefined } | { handled: true actionRequired: ActionRequiredType error: GigyaSdkErrorType | undefined } type OutputType = { handled: boolean regTokenExpired?: boolean actionRequired?: { loginId?: string callback: () => Promise<InternalOutputType> loginProviders?: GigyaSdkConflictingAccountType['loginProviders'] type: 'acceptToS' | 'conflictingAccount' | 'emailVerification' } error: GigyaSdkErrorType | undefined account?: GigyaSdkAccountInfoType | GigyaSdkRegisteredAccountType } const handleExpiredRegToken = ( error?: GigyaSdkErrorType ): Promise<InternalOutputType> => new Promise(async (resolve) => { resolve({ handled: true, regTokenExpired: true, error, }) }) const handlePendingVerification = ( error?: GigyaSdkErrorType ): Promise<InternalOutputType> => new Promise(async (resolve) => { await resendVerificationEmail({ noUID: true }) resolve({ actionRequired: { type: 'emailVerification' }, handled: true, error, }) }) const handleConflictingAccount = ( error?: GigyaSdkErrorType ): Promise<InternalOutputType> => new Promise(async (resolve) => { try { const conflictingAccount = error?.payload?.loginProviders ? error.payload : await getConflictingAccount() resolve({ error, handled: true, actionRequired: { type: 'conflictingAccount', loginId: conflictingAccount?.loginID, loginProviders: conflictingAccount?.loginProviders, }, }) } catch (e) { resolve({ error, handled: true, actionRequired: { type: 'conflictingAccount', }, }) } }) const onConsentSchemasAcceptance = ( options?: OptionsType ): Promise<InternalOutputType> => new Promise(async (resolve, reject) => { try { const unacceptedConsentSchemas = await getUnacceptedConsentSchemas< string[] >() if (unacceptedConsentSchemas) { await acceptConsentSchemas(unacceptedConsentSchemas, { noUID: true }) } const account = await getAccountInfo({ noUID: true }) if (!account.isVerified) { const state = await getState() const output = await handlePendingVerification(state.error) return resolve(output) } if (!account.isRegistered && !options?.noFinalize) { const response = await finalizeRegistration(options) if (!options?.noSetSession) { try { await setSession( response.sessionInfo.sessionToken, response.sessionInfo.sessionSecret ) } catch (e) {} } await clearErrorState() return resolve({ handled: true, account: response }) } await clearErrorState() resolve({ handled: true, account, }) } catch (e) { reject(e) } }) const handlePendingRegistration = ( error?: GigyaSdkErrorType, options?: OptionsType ): Promise<InternalOutputType> => new Promise(async (resolve, reject) => { try { const unacceptedConsentSchemas = await getUnacceptedConsentSchemas< string[] >() if (unacceptedConsentSchemas?.length) { if (options?.isRegistration) { const output = await onConsentSchemasAcceptance(options) return resolve(output) } return resolve({ handled: true, actionRequired: { type: 'acceptToS', callback: onConsentSchemasAcceptance, }, error, }) } const account = await getAccountInfo({ noUID: true }) if (!account.isVerified) { const output = await handlePendingVerification(error) return resolve(output) } if (!account.isRegistered && !options?.noFinalize) { const response = await finalizeRegistration(options) if (!options?.noSetSession) { try { await setSession( response.sessionInfo.sessionToken, response.sessionInfo.sessionSecret ) } catch (e) {} } resolve({ handled: true, account: response }) await clearErrorState() } resolve({ handled: false, error }) } catch (e) { reject(e) } }) export default function ( type: ProviderType, options?: OptionsType ): Promise<OutputType> { return new Promise(async (resolve, reject) => { try { const state = await getState() const error = options?.error || state.error let output: InternalOutputType = { handled: false, error } if (error && (await isGigyaError(error))) { await saveAuthenticationAttempt(type, error) } else { return resolve(output) } if (!state.regToken?.isStillValid) { output = await handleExpiredRegToken(error) return resolve(output as OutputType) } if ( error?.payload?.errorCode !== GigyaSdkErrorCodes.ConflictingAccount && error?.code === GigyaSdkErrors.ConflictingAccount ) { output = await handleConflictingAccount(error) return resolve(output as OutputType) } if ( error?.payload?.validationErrors?.filter( (validationError) => validationError.fieldName === 'email' ) ) { output = await handleConflictingAccount(error) return resolve(output as OutputType) } switch (error?.payload?.errorCode) { case GigyaSdkErrorCodes.PendingRegistration: output = await handlePendingRegistration(error, options) break case GigyaSdkErrorCodes.PendingVerification: output = await handlePendingVerification(error) break case GigyaSdkErrorCodes.ConflictingAccount: output = await handleConflictingAccount(error) break default: break } resolve(output as OutputType) } catch (err) { reject(err) } }) }