Skip to content

Commit

Permalink
chore: show alert error for forbidden analytics event (#3692)
Browse files Browse the repository at this point in the history
Co-authored-by: tomiir <[email protected]>
  • Loading branch information
magiziz and tomiir authored Jan 21, 2025
1 parent 1ea9f7d commit 5472c34
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 7 deletions.
23 changes: 23 additions & 0 deletions .changeset/tricky-spies-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
'@reown/appkit-common': patch
'@reown/appkit-core': patch
'@reown/appkit-adapter-bitcoin': patch
'@reown/appkit-adapter-ethers': patch
'@reown/appkit-adapter-ethers5': patch
'@reown/appkit-adapter-solana': patch
'@reown/appkit-adapter-wagmi': patch
'@reown/appkit': patch
'@reown/appkit-utils': patch
'@reown/appkit-cdn': patch
'@reown/appkit-cli': patch
'@reown/appkit-experimental': patch
'@reown/appkit-polyfills': patch
'@reown/appkit-scaffold-ui': patch
'@reown/appkit-siwe': patch
'@reown/appkit-siwx': patch
'@reown/appkit-ui': patch
'@reown/appkit-wallet': patch
'@reown/appkit-wallet-button': patch
---

Added an alert error if the analytics event fails with a forbidden status.
1 change: 1 addition & 0 deletions packages/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export { ParseUtil } from './src/utils/ParseUtil.js'
export {
SafeLocalStorage,
SafeLocalStorageKeys,
isSafe,
type SafeLocalStorageKey,
getSafeConnectorIdKey
} from './src/utils/SafeLocalStorage.js'
Expand Down
3 changes: 2 additions & 1 deletion packages/common/src/utils/ConstantsUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ export const ConstantsUtil = {
'0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9'
],
HTTP_STATUS_CODES: {
SERVICE_UNAVAILABLE: 503
SERVICE_UNAVAILABLE: 503,
FORBIDDEN: 403
},
UNSUPPORTED_NETWORK_NAME: 'Unknown Network'
} as const
2 changes: 1 addition & 1 deletion packages/common/src/utils/SafeLocalStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,6 @@ export const SafeLocalStorage = {
}
}

function isSafe(): boolean {
export function isSafe(): boolean {
return typeof window !== 'undefined' && typeof localStorage !== 'undefined'
}
29 changes: 27 additions & 2 deletions packages/core/src/controllers/EventsController.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { proxy, subscribe as sub } from 'valtio/vanilla'

import { ConstantsUtil, isSafe } from '@reown/appkit-common'

import { CoreHelperUtil } from '../utils/CoreHelperUtil.js'
import { FetchUtil } from '../utils/FetchUtil.js'
import type { Event } from '../utils/TypeUtil.js'
import { AlertController } from './AlertController.js'
import { OptionsController } from './OptionsController.js'

// -- Helpers ------------------------------------------- //
Expand All @@ -13,12 +16,14 @@ const excluded = ['MODAL_CREATED']
// -- Types --------------------------------------------- //
export interface EventsControllerState {
timestamp: number
reportedErrors: Record<string, boolean>
data: Event
}

// -- State --------------------------------------------- //
const state = proxy<EventsControllerState>({
timestamp: Date.now(),
reportedErrors: {},
data: {
type: 'track',
event: 'MODAL_CREATED'
Expand Down Expand Up @@ -60,8 +65,28 @@ export const EventsController = {
props: payload.data
}
})
} catch {
// Catch silently

state.reportedErrors['FORBIDDEN'] = false
} catch (err) {
const isForbiddenError =
err instanceof Error &&
err.cause instanceof Response &&
err.cause.status === ConstantsUtil.HTTP_STATUS_CODES.FORBIDDEN &&
!state.reportedErrors['FORBIDDEN']

if (isForbiddenError) {
AlertController.open(
{
shortMessage: 'Invalid App Configuration',
longMessage: `Origin ${
isSafe() ? window.origin : 'uknown'
} not found on Allowlist - update configuration on cloud.reown.com`
},
'error'
)

state.reportedErrors['FORBIDDEN'] = true
}
}
},

Expand Down
1 change: 1 addition & 0 deletions packages/core/tests/controllers/ApiController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const networks = [

// -- Tests --------------------------------------------------------------------
beforeAll(() => {
global.URL.createObjectURL = vi.fn((file: Blob) => `blob:${file}`)
ChainController.initialize(
[
{
Expand Down
31 changes: 29 additions & 2 deletions packages/core/tests/controllers/EventsController.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { describe, expect, it } from 'vitest'
import { describe, expect, it, vi } from 'vitest'

import { EventsController } from '../../exports/index.js'
import { ConstantsUtil } from '@reown/appkit-common'

import { AlertController, EventsController, FetchUtil } from '../../exports/index.js'

// -- Setup --------------------------------------------------------------------
const event = { type: 'track', event: 'MODAL_CLOSE', properties: { connected: true } } as const
Expand All @@ -19,4 +21,29 @@ describe('EventsController', () => {
EventsController.sendEvent(event)
expect(EventsController.state.data).toEqual(event)
})

it('should trigger an alert error if the analytics event fails with a forbidden status', async () => {
const error = new Error('forbidden')
error.cause = new Response(null, {
status: ConstantsUtil.HTTP_STATUS_CODES.FORBIDDEN
})

vi.spyOn(AlertController, 'open')
vi.spyOn(FetchUtil.prototype, 'post').mockRejectedValue(error)

await EventsController._sendAnalyticsEvent({
...EventsController.state,
data: { type: 'track', event: 'MODAL_CLOSE', properties: { connected: true } }
})

expect(AlertController.open).toHaveBeenCalledWith(
{
shortMessage: 'Invalid App Configuration',
longMessage: expect.stringContaining('not found on Allowlist')
},
'error'
)

expect(EventsController.state.reportedErrors['FORBIDDEN']).toBe(true)
})
})
6 changes: 5 additions & 1 deletion packages/core/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import { defineProject } from 'vitest/config'

export default defineProject({})
export default defineProject({
test: {
environment: 'jsdom'
}
})

0 comments on commit 5472c34

Please sign in to comment.