Skip to content

Commit

Permalink
Implement SDK key format validation + fix broken tests
Browse files Browse the repository at this point in the history
  • Loading branch information
adams85 committed Oct 30, 2023
1 parent 35d6749 commit 3949d6d
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 9 deletions.
24 changes: 23 additions & 1 deletion src/ConfigCatClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,9 @@ export class ConfigCatClient implements IConfigCatClient {
private static get instanceCache() { return clientInstanceCache; }

static get<TMode extends PollingMode>(sdkKey: string, pollingMode: TMode, options: OptionsForPollingMode<TMode> | undefined | null, configCatKernel: IConfigCatKernel): IConfigCatClient {
const invalidSdkKeyError = "Invalid 'sdkKey' value";
if (!sdkKey) {
throw new Error("Invalid 'sdkKey' value");
throw new Error(invalidSdkKeyError);
}

const optionsClass =
Expand All @@ -253,6 +254,10 @@ export class ConfigCatClient implements IConfigCatClient {

const actualOptions = new optionsClass(sdkKey, configCatKernel.sdkType, configCatKernel.sdkVersion, options, configCatKernel.defaultCacheFactory, configCatKernel.eventEmitterFactory);

if (actualOptions.flagOverrides?.behaviour !== OverrideBehaviour.LocalOnly && !isValidSdkKey(sdkKey, actualOptions.baseUrlOverriden)) {
throw new Error(invalidSdkKeyError);
}

const [instance, instanceAlreadyCreated] = clientInstanceCache.getOrCreate(actualOptions, configCatKernel);

if (instanceAlreadyCreated && options) {
Expand Down Expand Up @@ -754,6 +759,23 @@ export class SettingKeyValue<TValue = SettingValue> {
public settingValue: TValue) { }
}

function isValidSdkKey(sdkKey: string, customBaseUrl: boolean) {
const proxyPrefix = "configcat-proxy/";

// NOTE: String.prototype.startsWith were introduced after ES5. We'd rather work around it instead of polyfilling it.
if (customBaseUrl && sdkKey.length > proxyPrefix.length && sdkKey.lastIndexOf(proxyPrefix, 0) === 0) {
return true;
}

const components = sdkKey.split("/");
const keyLength = 22;
switch (components.length) {
case 2: return components[0].length === keyLength && components[1].length === keyLength;
case 3: return components[0] === "configcat-sdk-1" && components[1].length === keyLength && components[2].length === keyLength;
default: return false;
}
}

function validateKey(key: string): void {
if (!key) {
throw new Error("Invalid 'key' value");
Expand Down
10 changes: 5 additions & 5 deletions test/ConfigCatClientTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ describe("ConfigCatClient", () => {
it(`get() should return cached instance ${passOptionsToSecondGet ? "with" : "without"} warning`, done => {
// Arrange

const sdkKey = "test";
const sdkKey = "test-67890123456789012/1234567890123456789012";

const logger = new FakeLogger(LogLevel.Debug);

Expand Down Expand Up @@ -896,7 +896,7 @@ describe("ConfigCatClient", () => {
it("dispose() should remove cached instance", done => {
// Arrange

const sdkKey = "test";
const sdkKey = "test-67890123456789012/1234567890123456789012";

const configCatKernel: FakeConfigCatKernel = { configFetcher: new FakeConfigFetcher(), sdkType: "common", sdkVersion: "1.0.0" };

Expand All @@ -921,7 +921,7 @@ describe("ConfigCatClient", () => {
it("dispose() should remove current cached instance only", done => {
// Arrange

const sdkKey = "test";
const sdkKey = "test-67890123456789012/1234567890123456789012";

const configCatKernel: FakeConfigCatKernel = { configFetcher: new FakeConfigFetcher(), sdkType: "common", sdkVersion: "1.0.0" };

Expand Down Expand Up @@ -961,7 +961,7 @@ describe("ConfigCatClient", () => {
it("disposeAll() should remove all cached instances", done => {
// Arrange

const sdkKey1 = "test1", sdkKey2 = "test2";
const sdkKey1 = "test1-7890123456789012/1234567890123456789012", sdkKey2 = "test2-7890123456789012/1234567890123456789012";

const configCatKernel: FakeConfigCatKernel = { configFetcher: new FakeConfigFetcher(), sdkType: "common", sdkVersion: "1.0.0" };

Expand Down Expand Up @@ -995,7 +995,7 @@ describe("ConfigCatClient", () => {
}
const isFinalizationRegistryAvailable = typeof FinalizationRegistry !== "undefined";

const sdkKey1 = "test1", sdkKey2 = "test2";
const sdkKey1 = "test1-7890123456789012/1234567890123456789012", sdkKey2 = "test2-7890123456789012/1234567890123456789012";

const logger = new FakeLogger(LogLevel.Debug);
const configCatKernel: FakeConfigCatKernel = { configFetcher: new FakeConfigFetcher(), sdkType: "common", sdkVersion: "1.0.0" };
Expand Down
6 changes: 3 additions & 3 deletions test/IndexTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe("ConfigCatClient index (main)", () => {
it("getClient ShouldCreateInstance - AutoPoll", () => {

const configCatKernel: FakeConfigCatKernel = { configFetcher: new FakeConfigFetcher(), sdkType: "common", sdkVersion: "1.0.0" };
const client: IConfigCatClient = configcatClient.getClient("APIKEY", PollingMode.AutoPoll, void 0, configCatKernel);
const client: IConfigCatClient = configcatClient.getClient("SDKKEY-890123456789012/1234567890123456789012", PollingMode.AutoPoll, void 0, configCatKernel);

try {
assert.isDefined(client);
Expand All @@ -23,7 +23,7 @@ describe("ConfigCatClient index (main)", () => {
it("getClient ShouldCreateInstance - LazyLoad", () => {

const configCatKernel: FakeConfigCatKernel = { configFetcher: new FakeConfigFetcher(), sdkType: "common", sdkVersion: "1.0.0" };
const client: IConfigCatClient = configcatClient.getClient("APIKEY", PollingMode.LazyLoad, void 0, configCatKernel);
const client: IConfigCatClient = configcatClient.getClient("SDKKEY-890123456789012/1234567890123456789012", PollingMode.LazyLoad, void 0, configCatKernel);

try {
assert.isDefined(client);
Expand All @@ -36,7 +36,7 @@ describe("ConfigCatClient index (main)", () => {
it("getClient ShouldCreateInstance - ManualPoll", () => {

const configCatKernel: FakeConfigCatKernel = { configFetcher: new FakeConfigFetcher(), sdkType: "common", sdkVersion: "1.0.0" };
const client: IConfigCatClient = configcatClient.getClient("APIKEY", PollingMode.ManualPoll, void 0, configCatKernel);
const client: IConfigCatClient = configcatClient.getClient("SDKKEY-890123456789012/1234567890123456789012", PollingMode.ManualPoll, void 0, configCatKernel);

try {
assert.isDefined(client);
Expand Down

0 comments on commit 3949d6d

Please sign in to comment.