Skip to content

Commit

Permalink
Hacking nango to catch user cancellation
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyxiao committed Oct 13, 2023
1 parent 3731d2a commit e19d462
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 10 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@
"[email protected]": "patches/[email protected]",
"[email protected]": "patches/[email protected]",
"[email protected]": "patches/[email protected]",
"[email protected]": "patches/[email protected]"
"[email protected]": "patches/[email protected]",
"@nangohq/[email protected]": "patches/@[email protected]"
},
"peerDependencyRules": {
"allowedVersions": {
Expand Down
3 changes: 2 additions & 1 deletion packages/cdk-core/frontend-utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export function useScript(src: string) {
return deferred.current.promise // TODO: return loaded / error also
}

export const CANCELLATION_TOKEN = 'CANCELLED'
/** Casting to `Error` type to suppress warning */
export const CANCELLATION_TOKEN = 'CANCELLED' as unknown as Error

/** Used by yodlee container among others */
export function DivContainer(props: {
Expand Down
26 changes: 20 additions & 6 deletions packages/engine-frontend/VeniceConnect.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client'

import type {AuthError} from '@nangohq/frontend'
import Nango from '@nangohq/frontend'
import {useMutation} from '@tanstack/react-query'
import {Link2, Loader2, RefreshCw, Trash2} from 'lucide-react'
Expand Down Expand Up @@ -46,6 +47,10 @@ import {makeUlid, R, titleCase, z} from '@usevenice/util'

import {_trpcReact} from './TRPCProvider'

function isNangoAuthError(err: unknown): err is AuthError {
return typeof err === 'object' && err != null && 'type' in err
}

type ConnectEventType = 'open' | 'close' | 'error'

export interface VeniceConnectProps extends UIPropsNoChildren {
Expand Down Expand Up @@ -130,6 +135,11 @@ export function VeniceConnect(props: VeniceConnectProps) {
type Catalog = RouterOutput['getIntegrationCatalog']
type ProviderMeta = Catalog[string]

// TODOD: Dedupe this with app-config/constants
const __DEBUG__ = Boolean(
typeof window !== 'undefined' && window.location.hostname === 'localhost',
)

/** Need _VeniceConnect integrationIds to not have useConnectHook execute unreliably */
export function _VeniceConnect({
catalog,
Expand All @@ -147,7 +157,9 @@ export function _VeniceConnect({
_trpcReact.getPublicEnv.useQuery().data?.NEXT_PUBLIC_NANGO_PUBLIC_KEY

const nango = React.useMemo(
() => nangoPublicKey && new Nango({publicKey: nangoPublicKey}),
() =>
nangoPublicKey &&
new Nango({publicKey: nangoPublicKey, debug: __DEBUG__}),
[nangoPublicKey],
)

Expand Down Expand Up @@ -216,12 +228,14 @@ export function _VeniceConnect({
if (!nango) {
throw new Error('Missing nango public key')
}
return await nango.auth(integrationId, resoId).then((r) => {
console.log('auth', r)
if ('message' in r) {
throw new Error(`${r.type}: ${r.message}`)
return await nango.auth(integrationId, resoId).catch((err) => {
if (isNangoAuthError(err)) {
if (err.type === 'user_cancelled') {
throw CANCELLATION_TOKEN
}
throw new Error(`${err.type}: ${err.message}`)
}
return r
throw err
})
}
}
Expand Down
62 changes: 62 additions & 0 deletions patches/@[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
diff --git a/dist/index.d.ts b/dist/index.d.ts
index 91d370b7ada12e8b27cc6706151d676b27a72c20..bee8cc225dc1e621bbab0902e0d7648cb81e1845 100644
--- a/dist/index.d.ts
+++ b/dist/index.d.ts
@@ -1,4 +1,5 @@
-type AuthError = {
+/** Gets thrown by `create` and `auth` methods */
+export type AuthError = {
message: string;
type: string;
};
@@ -14,14 +15,16 @@ export default class Nango {
publicKey: string;
debug?: boolean;
});
+ /** @throws `AuthError` */
create(providerConfigKey: string, connectionId: string, connectionConfig: ConnectionConfig): Promise<{
providerConfigKey: string;
connectionId: string;
- } | AuthError>;
+ }>;
+ /** @throws `AuthError` */
auth(providerConfigKey: string, connectionId: string, conectionConfigOrCredentials?: ConnectionConfig | BasicApiCredentials | ApiKeyCredentials): Promise<{
providerConfigKey: string;
connectionId: string;
- } | AuthError>;
+ }>;
convertCredentialsToConfig(credentials: BasicApiCredentials | ApiKeyCredentials): ConnectionConfig;
private apiAuth;
private toQueryString;
diff --git a/dist/index.js b/dist/index.js
index 3ee0e9e9a72cb4d3fd611066811dd494b6839c7f..0014509fc6df476c7e662f4e7a44bd5dc355523e 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -217,6 +217,7 @@ class AuthorizationModal {
this.swClient.onmessage = (message) => {
this.handleMessage(message, successHandler, errorHandler);
};
+ this.errorHandler = errorHandler;
}
/**
* Handles the messages received from the Nango server via WebSocket.
@@ -269,6 +270,19 @@ class AuthorizationModal {
*/
open(wsClientId) {
this.modal.location = this.url + '&ws_client_id=' + wsClientId;
+ // @see https://github.com/NangoHQ/nango/pull/1073 for a real fix
+ // Can remove this patch once it merges into master and gets released
+ this.interval = setInterval(() => {
+ if (this.modal?.closed) {
+ setTimeout(() => {
+ if (this.swClient.readyState !== this.swClient.CLOSED) {
+ this.errorHandler('user_cancelled', 'User cancelled the authorization process.')
+ this.swClient.close();
+ }
+ clearInterval(this.interval)
+ }, 500)
+ }
+ }, 500)
return this.modal;
}
/**
8 changes: 6 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e19d462

Please sign in to comment.