Skip to content

Commit

Permalink
Update to Insurely Blocks API
Browse files Browse the repository at this point in the history
  • Loading branch information
robinandeer committed Apr 21, 2023
1 parent a4b4be9 commit b0a022d
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 59 deletions.
1 change: 1 addition & 0 deletions apps/store/.env.local.example
Expand Up @@ -51,3 +51,4 @@ EDGE_CONFIG_MANAGE_API_URL=https://api.vercel.com/v1/edge-config/:configId/items
EDGE_CONFIG_MANAGE_API_TOKEN=:token

NEXT_PUBLIC_CUSTOMER_FIRST_SCRIPT=
NEXT_PUBLIC_INSURELY_CUSTOMER_ID=
39 changes: 25 additions & 14 deletions apps/store/index.d.ts
Expand Up @@ -34,31 +34,42 @@ type MerchantCallbackFunction = (data: MerchantCallbackData) => void
type MerchantCallbackData = { accountId: string }
type TrustlyOptions = { locale: string }

type InsurelyPrefilledInput = {
company: string
SWEDISH_PERSONAL_NUMBER: string
}
type InsurelyClientParams = {
fontType?: 'main' | 'secondary'
hideResultsView?: boolean
language?: 'en' | 'no' | 'sv' | 'da'
prefilledInput?: Partial<InsurelyPrefilledInput>
}

declare global {
interface Window {
TrustlyWidget: {
init: TrustlyInitFunction
}
dataLayer: DataLayerObject[]

// Insurely
setClientParams?: (params: InsurelyClientParams) => void

// Customer First (C1)
customerFirstAPI?: {
openWidget(): void
closeWidget(): void
}

// Insurely
insurely?: {
config?: InsurelyConfig
prefill?: InsurelyPrefill
}
}
}

type InsurelyConfig = {
customerId?: string
configName?: string
showCloseButton?: boolean
language?: 'en' | 'no' | 'sv' | 'da'
dataAggregation?: {
hideResultsView?: boolean
}
}

type InsurelyPrefill = {
user?: {
swedishPersonalNumber?: string
}
dataAggregation?: {
company?: string
}
}
8 changes: 6 additions & 2 deletions apps/store/next-csp.config.js
Expand Up @@ -29,7 +29,9 @@ const scriptSrc = [
// GTM injected scripts
...gtmInjectedOrigins,

'https://dc.insurely.com',
// Insurely
'https://blocks.insurely.com',

'https://vercel.live',
"'unsafe-inline'",
"'unsafe-eval'",
Expand Down Expand Up @@ -99,7 +101,6 @@ const connectSrc = [
"'self'",
]
const frameSrc = [
'https://dc.insurely.com',
'https://player.vimeo.com',
'https://vercel.live', // Vercel Live
'https://www.googletagmanager.com',
Expand All @@ -115,6 +116,9 @@ const frameSrc = [
'https://*.snapchat.com',
'https://*.hotjar.com',

// Insurely
'https://blocks.insurely.com',

"'self'",
]

Expand Down
Expand Up @@ -12,7 +12,7 @@ import {
useInsurelyDataCollectionCreateMutation,
} from '@/services/apollo/generated'
import { Flags } from '@/services/Flags/Flags'
import { InsurelyIframe, insurelyPrefillInput } from '@/services/Insurely/Insurely'
import { InsurelyIframe, setInsurelyConfig } from '@/services/Insurely/Insurely'
import {
INSURELY_IFRAME_MAX_HEIGHT,
INSURELY_IFRAME_MAX_WIDTH,
Expand Down Expand Up @@ -64,16 +64,19 @@ export const CurrentInsuranceField = (props: Props) => {
priceIntentId,
onCompleted(updatedPriceIntent) {
const externalInsurer = updatedPriceIntent.externalInsurer
const personalNumber = shopSession?.customer?.ssn
const ssn = shopSession?.customer?.ssn

if (!externalInsurer) {
datadogLogs.logger.warn('Failed to update external insurer', { priceIntentId })
return
}

if (insurelyClientId && personalNumber) {
if (insurelyClientId && ssn) {
compare(externalInsurer, insurelyClientId)
insurelyPrefillInput({ company: externalInsurer.insurelyId ?? undefined, personalNumber })
setInsurelyConfig({
company: externalInsurer.insurelyId ?? undefined,
ssn,
})
} else {
confirm(externalInsurer)
}
Expand Down Expand Up @@ -155,7 +158,8 @@ export const CurrentInsuranceField = (props: Props) => {
{state.type === 'COMPARE' ? (
<DialogIframeWindow>
<InsurelyIframe
clientId={state.insurelyClientId}
// TODO: Switch to Insurely config name when we have it
configName={state.insurelyClientId}
onCollection={handleInsurelyCollection}
onClose={close}
onCompleted={handleInsurelyCompleted}
Expand Down
83 changes: 45 additions & 38 deletions apps/store/src/services/Insurely/Insurely.tsx
Expand Up @@ -2,12 +2,13 @@

import styled from '@emotion/styled'
import Script from 'next/script'
import { useEffect, useMemo } from 'react'
import { useEffect } from 'react'
import { Language } from '@/utils/l10n/types'
import { useCurrentLocale } from '@/utils/l10n/useCurrentLocale'

const IFRAME_URL = 'https://dc.insurely.com/v2/select-authentication'
const BOOTSTRAP_SCRIPT_URL = 'https://dc.insurely.com/v2/assets/js/dc-bootstrap.js'
const PREFILL_STORE: Array<Record<string, string>> = []
const CUSTOMER_ID = process.env.NEXT_PUBLIC_INSURELY_CUSTOMER_ID as string
const IFRAME_URL = 'https://blocks.insurely.com/'
const BOOTSTRAP_SCRIPT_URL = 'https://blocks.insurely.com/assets/bootstrap.js'

enum EventName {
APP_LOADED = 'APP_LOADED',
Expand All @@ -24,17 +25,15 @@ type InsurelyMessage =
| { name: EventName.RESULTS }

type InsurelyIframeProps = {
clientId: string
configName: string
onLoaded?: () => void
onClose?: () => void
onCollection?: (collectionId: string) => void
onCompleted?: () => void
}

export const InsurelyIframe = (props: InsurelyIframeProps) => {
const { clientId, onLoaded, onClose, onCollection, onCompleted } = props
const { language } = useCurrentLocale()

const { onLoaded, onClose, onCollection, onCompleted } = props
useEffect(() => {
const handleMessage = ({ data }: MessageEvent<InsurelyMessage>) => {
switch (data.name) {
Expand All @@ -55,26 +54,17 @@ export const InsurelyIframe = (props: InsurelyIframeProps) => {
return () => window.removeEventListener('message', handleMessage)
}, [onLoaded, onClose, onCollection, onCompleted])

const handleLoad = () => {
const prefilledInput = PREFILL_STORE.shift()
window.setClientParams?.({
fontType: 'secondary',
hideResultsView: true,
language,
...(prefilledInput && { prefilledInput }),
})
}

const iFrameSrc = useMemo(() => {
const queryParams = new URLSearchParams({ clientId })
return `${IFRAME_URL}?${queryParams.toString()}`
}, [clientId])
const { language } = useCurrentLocale()
useEffect(() => {
setInsurelyConfig({ customerId: CUSTOMER_ID, configName: props.configName, language })
}, [language, props.configName])

return (
<>
<StyledIframe
title="Insurely"
src={iFrameSrc}
id="insurely-data-aggregation"
title="insurely-data-aggregation"
src={IFRAME_URL}
sandbox="allow-scripts
allow-same-origin
allow-popups
Expand All @@ -83,26 +73,43 @@ export const InsurelyIframe = (props: InsurelyIframeProps) => {
allow-top-navigation"
/>

<Script strategy="afterInteractive" src={BOOTSTRAP_SCRIPT_URL} onLoad={handleLoad} />
<Script strategy="afterInteractive" src={BOOTSTRAP_SCRIPT_URL} />
</>
)
}

type InsurelyClientParams = Partial<{ company: string; personalNumber: string }>

export const insurelyPrefillInput = ({ personalNumber, company }: InsurelyClientParams) => {
const prefilledInput = {
...(personalNumber && { SWEDISH_PERSONAL_NUMBER: personalNumber }),
...(company && { company }),
}
type InsurelyConfig = {
customerId?: string
configName?: string
company?: string
ssn?: string
language?: Language
}

// If the iframe is already loaded, we can set the prefilled input directly
if (window.setClientParams) {
return window.setClientParams({ prefilledInput })
export const setInsurelyConfig = (config: InsurelyConfig) => {
window.insurely = {
config: {
...window.insurely?.config,
...(config.customerId && { customerId: config.customerId }),
...(config.configName && { configName: config.configName }),
...(config.language && { language: config.language }),

// showCloseButton: true,
dataAggregation: {
hideResultsView: true,
},
},
prefill: {
dataAggregation: {
...window.insurely?.prefill?.dataAggregation,
...(config.company && { company: config.company }),
},
user: {
...window.insurely?.prefill?.user,
...(config.ssn && { swedishPersonalNumber: config.ssn }),
},
},
}

// Otherwise we store the prefilled input and set it when the iframe is loaded
PREFILL_STORE.push(prefilledInput)
}

const StyledIframe = styled.iframe({ border: 0 })

0 comments on commit b0a022d

Please sign in to comment.