Skip to content

Commit a1f9ad8

Browse files
authored
fix: /client/features should accept client tokens configured (#141)
1 parent c8bd759 commit a1f9ad8

File tree

3 files changed

+80
-2
lines changed

3 files changed

+80
-2
lines changed

src/test/client.mock.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,16 @@ class MockClient extends EventEmitter implements IClient {
1919
}
2020

2121
getFeatureToggleDefinitions(): FeatureInterface[] {
22-
throw new Error('Method not implemented.');
22+
return this.toggles.map((t) => ({
23+
name: t.name,
24+
strategies: [{ name: 'default', parameters: {}, constraints: [] }],
25+
enabled: t.enabled,
26+
project: 'default',
27+
stale: false,
28+
type: 'release',
29+
variants: [],
30+
impressionData: false,
31+
}));
2332
}
2433

2534
isReady(): boolean {

src/test/unleash-proxy.test.ts

+56
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,62 @@ test('Should return all feature toggles', () => {
623623
});
624624
});
625625

626+
test('/client/features should return toggle definitions', () => {
627+
const client = new MockClient([
628+
{ name: 'a', enabled: true, impressionData: false },
629+
{ name: 'b', enabled: false, impressionData: false },
630+
{ name: 'c', enabled: true, impressionData: true },
631+
]);
632+
633+
const proxySecrets = ['sdf'];
634+
const app = createApp(
635+
{
636+
unleashUrl,
637+
unleashApiToken,
638+
proxySecrets,
639+
enableAllEndpoint: true,
640+
expServerSideSdkConfig: { tokens: ['server-side'] },
641+
},
642+
client,
643+
);
644+
client.emit('ready');
645+
646+
return request(app)
647+
.get('/proxy/client/features')
648+
.set('Authorization', 'server-side')
649+
.expect(200)
650+
.expect((res) => {
651+
expect(res.body.features.length).toBe(3);
652+
expect(res.body.features[0].strategies.length).toBe(1);
653+
});
654+
});
655+
656+
test('/client/features should not accept proxy secret', () => {
657+
const client = new MockClient([
658+
{ name: 'a', enabled: true, impressionData: false },
659+
{ name: 'b', enabled: false, impressionData: false },
660+
{ name: 'c', enabled: true, impressionData: true },
661+
]);
662+
663+
const proxySecrets = ['sdf'];
664+
const app = createApp(
665+
{
666+
unleashUrl,
667+
unleashApiToken,
668+
proxySecrets,
669+
enableAllEndpoint: true,
670+
expServerSideSdkConfig: { tokens: ['server-side'] },
671+
},
672+
client,
673+
);
674+
client.emit('ready');
675+
676+
return request(app)
677+
.get('/proxy/client/features')
678+
.set('Authorization', 'sdf')
679+
.expect(401);
680+
});
681+
626682
test('Should return all feature toggles via POST', () => {
627683
const client = new MockClient([
628684
{ name: 'a', enabled: true, impressionData: false },

src/unleash-proxy.ts

+14-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ If you don't provide the \`toggles\` property, then this operation functions exa
206206
tags: ['Server-side client'],
207207
}),
208208
this.readyMiddleware.bind(this),
209-
this.clientTokenMiddleware.bind(this),
209+
this.expServerSideTokenMiddleware.bind(this),
210210
this.unleashApi.bind(this),
211211
);
212212

@@ -308,6 +308,19 @@ If you don't provide the \`toggles\` property, then this operation functions exa
308308
}
309309
}
310310

311+
private expServerSideTokenMiddleware(
312+
req: Request,
313+
res: Response,
314+
next: NextFunction,
315+
) {
316+
const apiToken = req.header(this.clientKeysHeaderName);
317+
if (!apiToken || !this.serverSideTokens.includes(apiToken)) {
318+
res.sendStatus(401);
319+
} else {
320+
next();
321+
}
322+
}
323+
311324
async getAllToggles(
312325
req: Request,
313326
res: Response<FeaturesSchema | string>,

0 commit comments

Comments
 (0)