Skip to content

Commit cdc932e

Browse files
committed
WEB-579: make API gateway tenant header name configurable
1 parent afebb0e commit cdc932e

4 files changed

Lines changed: 48 additions & 8 deletions

File tree

src/app/login/login.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,8 @@ export class LoginComponent implements OnInit, OnDestroy {
208208
}
209209
const tenantIds = environment.fineractPlatformTenantIds
210210
.split(',')
211-
.map((id) => id.trim())
212-
.filter((id) => id.length > 0);
211+
.map((id: string) => id.trim())
212+
.filter((id: string) => id.length > 0);
213213
if (tenantIds.length === 0 || (tenantIds.length === 1 && tenantIds[0] === 'default')) {
214214
return false;
215215
}

src/app/zitadel/token.interceptor.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,15 @@ export class TokenInterceptor implements HttpInterceptor {
1919

2020
public environment = environment;
2121
FINERACT_PLATFORM_TENANT_IDENTIFIER = environment.fineractPlatformTenantId;
22+
// Name used to send the Fineract tenant identifier header.
23+
// The runtime key is `apiGatewayHeaderName` to allow gateway/runtime injection,
24+
// but this value represents the Fineract tenant header name.
25+
FINERACT_TENANT_HEADER_NAME = environment.apiGatewayHeaderName || 'Fineract-Platform-TenantId';
2226

2327
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
2428
const token = this.authService.getAccessToken();
2529
let headersConfig: { [key: string]: string } = {
26-
'Fineract-Platform-TenantId': this.FINERACT_PLATFORM_TENANT_IDENTIFIER,
30+
[this.FINERACT_TENANT_HEADER_NAME]: this.FINERACT_PLATFORM_TENANT_IDENTIFIER,
2731
'Content-Type': req.headers.get('Content-Type') || 'application/json'
2832
};
2933
const publicEndpoints = [
@@ -56,7 +60,7 @@ export class TokenInterceptor implements HttpInterceptor {
5660
const retriedReq = request.clone({
5761
setHeaders: {
5862
Authorization: `Bearer ${newToken}`,
59-
'Fineract-Platform-TenantId': this.FINERACT_PLATFORM_TENANT_IDENTIFIER,
63+
[this.FINERACT_TENANT_HEADER_NAME]: this.FINERACT_PLATFORM_TENANT_IDENTIFIER,
6064
'Content-Type': request.headers.get('Content-Type') || 'application/json'
6165
}
6266
});

src/environments/environment.prod.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,19 @@ const provider = loadedEnv['apiProvider'];
1717
const parsedMinLength = Number(loadedEnv.minPasswordLength);
1818
const resolvedMinPasswordLength = Number.isInteger(parsedMinLength) && parsedMinLength > 0 ? parsedMinLength : 8;
1919

20-
export const environment = {
20+
// Validate and normalize apiGatewayHeaderName (RFC 7230 token format)
21+
const resolvedApiGatewayHeaderName =
22+
typeof loadedEnv.apiGatewayHeaderName === 'string' &&
23+
/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test(loadedEnv.apiGatewayHeaderName.trim())
24+
? loadedEnv.apiGatewayHeaderName.trim()
25+
: 'Fineract-Platform-TenantId';
26+
27+
interface IEnvironment {
28+
[key: string]: any;
29+
apiGatewayHeaderName: string;
30+
}
31+
32+
export const environment: IEnvironment = {
2133
production: true,
2234
version: env.mifos_x.version,
2335
hash: env.mifos_x.hash,
@@ -145,7 +157,13 @@ export const environment = {
145157
oidcClientId: loadedEnv['oidcClientId'] || loadedEnv['FINERACT_PLUGIN_OIDC_CLIENT_ID'] || '',
146158
oidcApiUrl: loadedEnv['oidcApiUrl'] || loadedEnv['FINERACT_PLUGIN_OIDC_API_URL'] || '',
147159
oidcFrontUrl: loadedEnv['oidcFrontUrl'] || loadedEnv['FINERACT_PLUGIN_OIDC_FRONTEND_URL'] || ''
148-
}
160+
},
161+
/**
162+
* Name of the header used to signal the tenant/platform to the API gateway
163+
* Default kept for backward compatibility with existing deployments and tests
164+
* Validated against RFC 7230 token format; whitespace trimmed; invalid values fallback to default.
165+
*/
166+
apiGatewayHeaderName: resolvedApiGatewayHeaderName
149167
};
150168

151169
// Server URL

src/environments/environment.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,19 @@ const loadedEnv = window.env || {};
2020
const parsedMinLength = Number(loadedEnv.minPasswordLength);
2121
const resolvedMinPasswordLength = Number.isInteger(parsedMinLength) && parsedMinLength > 0 ? parsedMinLength : 8;
2222

23-
export const environment = {
23+
// Validate and normalize apiGatewayHeaderName (RFC 7230 token format)
24+
const resolvedApiGatewayHeaderName =
25+
typeof loadedEnv.apiGatewayHeaderName === 'string' &&
26+
/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test(loadedEnv.apiGatewayHeaderName.trim())
27+
? loadedEnv.apiGatewayHeaderName.trim()
28+
: 'Fineract-Platform-TenantId';
29+
30+
interface IEnvironment {
31+
[key: string]: any;
32+
apiGatewayHeaderName: string;
33+
}
34+
35+
export const environment: IEnvironment = {
2436
production: false,
2537
version: env.mifos_x.version,
2638
hash: env.mifos_x.hash,
@@ -149,7 +161,13 @@ export const environment = {
149161
oidcClientId: loadedEnv.oidcClientId || loadedEnv.FINERACT_PLUGIN_OIDC_CLIENT_ID || '',
150162
oidcApiUrl: loadedEnv.oidcApiUrl || loadedEnv.FINERACT_PLUGIN_OIDC_API_URL || '',
151163
oidcFrontUrl: loadedEnv.oidcFrontUrl || loadedEnv.FINERACT_PLUGIN_OIDC_FRONTEND_URL || ''
152-
}
164+
},
165+
/**
166+
* Name of the header used to signal the tenant/platform to the API gateway
167+
* Default kept for backward compatibility with existing deployments and tests
168+
* Validated against RFC 7230 token format; whitespace trimmed; invalid values fallback to default.
169+
*/
170+
apiGatewayHeaderName: resolvedApiGatewayHeaderName
153171
};
154172

155173
// Server URL

0 commit comments

Comments
 (0)