diff --git a/package.json b/package.json index 5b3dc2a..0779c6d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@eppo/js-client-sdk-common", - "version": "4.11.0", + "version": "4.12.0", "description": "Common library for Eppo JavaScript SDKs (web, react native, and node)", "main": "dist/index.js", "files": [ diff --git a/src/api-endpoints.ts b/src/api-endpoints.ts index 6d45c0c..f00eb29 100644 --- a/src/api-endpoints.ts +++ b/src/api-endpoints.ts @@ -3,6 +3,7 @@ import { UFC_ENDPOINT, BANDIT_ENDPOINT, PRECOMPUTED_FLAGS_ENDPOINT, + FLAG_OVERRIDES_KEY_VALIDATION_URL, } from './constants'; import { IQueryParams, IQueryParamsWithSubject } from './http-client'; @@ -36,4 +37,8 @@ export default class ApiEndpoints { precomputedFlagsEndpoint(): URL { return this.endpoint(PRECOMPUTED_FLAGS_ENDPOINT); } + + flagOverridesKeyValidationEndpoint(): URL { + return this.endpoint(FLAG_OVERRIDES_KEY_VALIDATION_URL); + } } diff --git a/src/client/eppo-client.ts b/src/client/eppo-client.ts index e54143b..60292b5 100644 --- a/src/client/eppo-client.ts +++ b/src/client/eppo-client.ts @@ -213,7 +213,8 @@ export default class EppoClient { return undefined; } const payload: OverridePayload = this.overrideValidator.parseOverridePayload(overridePayload); - await this.overrideValidator.validateKey(payload.browserExtensionKey); + const baseUrl = this.configurationRequestParameters?.baseUrl; + await this.overrideValidator.validateKey(payload.browserExtensionKey, baseUrl); return payload.overrides; } @@ -222,7 +223,7 @@ export default class EppoClient { * to it without affecting the original EppoClient singleton. Useful for * applying overrides in a shared Node instance, such as a web server. */ - withOverrides(overrides: Record): EppoClient { + withOverrides(overrides: Record | undefined): EppoClient { if (overrides && Object.keys(overrides).length) { const copy = shallowClone(this); copy.overrideStore = new MemoryOnlyConfigurationStore(); diff --git a/src/constants.ts b/src/constants.ts index f7c3b30..22f165e 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -9,6 +9,7 @@ export const DEFAULT_POLL_CONFIG_REQUEST_RETRIES = 7; export const BASE_URL = 'https://fscdn.eppo.cloud/api'; export const UFC_ENDPOINT = '/flag-config/v1/config'; export const BANDIT_ENDPOINT = '/flag-config/v1/bandits'; +export const FLAG_OVERRIDES_KEY_VALIDATION_URL = '/flag-overrides/v1/validate-key'; export const PRECOMPUTED_BASE_URL = 'https://fs-edge-assignment.eppo.cloud'; export const PRECOMPUTED_FLAGS_ENDPOINT = '/assignments'; export const SESSION_ASSIGNMENT_CONFIG_LOADED = 'eppo-session-assignment-config-loaded'; diff --git a/src/override-validator.ts b/src/override-validator.ts index c2a5986..77ceec5 100644 --- a/src/override-validator.ts +++ b/src/override-validator.ts @@ -1,17 +1,20 @@ +import ApiEndpoints from './api-endpoints'; import { TLRUCache } from './cache/tlru-cache'; import { Variation } from './interfaces'; import { FlagKey } from './types'; const FIVE_MINUTES_IN_MS = 5 * 3600 * 1000; -const KEY_VALIDATION_URL = 'https://eppo.cloud/api/flag-overrides/v1/validate-key'; export interface OverridePayload { browserExtensionKey: string; overrides: Record; } -export const sendValidationRequest = async (browserExtensionKey: string) => { - const response = await fetch(KEY_VALIDATION_URL, { +export const sendValidationRequest = async ( + browserExtensionKey: string, + validationEndpoint: string, +) => { + const response = await fetch(validationEndpoint, { method: 'POST', body: JSON.stringify({ key: browserExtensionKey, @@ -63,11 +66,12 @@ export class OverrideValidator { } } - async validateKey(browserExtensionKey: string) { + async validateKey(browserExtensionKey: string, baseUrl: string | undefined) { if (this.validKeyCache.get(browserExtensionKey) === 'true') { return true; } - await sendValidationRequest(browserExtensionKey); + const endpoint = new ApiEndpoints({ baseUrl }).flagOverridesKeyValidationEndpoint().toString(); + await sendValidationRequest(browserExtensionKey, endpoint); this.validKeyCache.set(browserExtensionKey, 'true'); } }