| 120 | }); |
| 121 | |
| 122 | class SalesforceCRMService implements CRM { |
| 123 | private integrationName = ""; |
| 124 | private conn!: Promise<Connection>; |
| 125 | private log: typeof logger; |
| 126 | private calWarnings: string[] = []; |
| 127 | private appOptions: z.infer<typeof appDataSchema>; |
| 128 | private doNotCreateEvent = false; |
| 129 | private fallbackToContact = false; |
| 130 | private accessToken: string; |
| 131 | private instanceUrl: string; |
| 132 | private hasAttemptedRefresh = false; |
| 133 | private credentialId: number; |
| 134 | private describeCache = new Map<string, Set<string>>(); |
| 135 | |
| 136 | constructor(credential: CredentialPayload, appOptions: z.infer<typeof appDataSchema>, testMode = false) { |
| 137 | this.integrationName = "salesforce_other_calendar"; |
| 138 | this.credentialId = credential.id; |
| 139 | if (!testMode) { |
| 140 | this.conn = this.getClient(credential).then((c) => c); |
| 141 | } |
| 142 | this.log = logger.getSubLogger({ prefix: [`[[lib] ${this.integrationName}`] }); |
| 143 | this.appOptions = appOptions; |
| 144 | const credentialKey = credential.key as unknown as ExtendedTokenResponse; |
| 145 | this.accessToken = credentialKey.access_token; |
| 146 | this.instanceUrl = credentialKey.instance_url; |
| 147 | } |
| 148 | |
| 149 | public getAppOptions() { |
| 150 | return this.appOptions; |
| 151 | } |
| 152 | |
| 153 | /** |
| 154 | * Refreshes the Salesforce access token and optionally introspects to get/update token_lifetime. |
| 155 | * @param forceIntrospection - If true, always introspect to recalibrate token_lifetime (e.g., after unexpected expiry) |
| 156 | * @param existingTokenLifetime - The current token_lifetime to reuse if not forcing introspection |
| 157 | */ |
| 158 | private refreshAccessToken = async ({ |
| 159 | refreshToken, |
| 160 | forceIntrospection, |
| 161 | existingTokenLifetime, |
| 162 | }: { |
| 163 | refreshToken: string; |
| 164 | forceIntrospection: boolean; |
| 165 | existingTokenLifetime?: number; |
| 166 | }) => { |
| 167 | const { consumer_key, consumer_secret } = await getSalesforceAppKeys(); |
| 168 | |
| 169 | const response = await fetch("https://login.salesforce.com/services/oauth2/token", { |
| 170 | method: "POST", |
| 171 | headers: { |
| 172 | "Content-Type": "application/x-www-form-urlencoded", |
| 173 | }, |
| 174 | body: new URLSearchParams({ |
| 175 | grant_type: "refresh_token", |
| 176 | client_id: consumer_key, |
| 177 | client_secret: consumer_secret, |
| 178 | refresh_token: refreshToken, |
| 179 | }), |
nothing calls this directly
no test coverage detected