Skip to content

Commit 453b5fc

Browse files
CHANDRAHARSHITmirarifhasanjamesgeorge007
authored
feat: add configurable session cookie name (hoppscotch#5425)
Added support for overriding the default session cookie name using the `INFRA.SESSION_COOKIE_NAME` config or the `SESSION_COOKIE_NAME` environment variable. This helps compatibility with proxies or load balancers that cannot handle cookie names containing dots. --- Co-authored-by: mirarifhasan <[email protected]> Co-authored-by: jamesgeorge007 <[email protected]>
1 parent 8f7146b commit 453b5fc

File tree

8 files changed

+68
-3
lines changed

8 files changed

+68
-3
lines changed

packages/hoppscotch-backend/src/infra-config/helper.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ export async function getDefaultInfraConfigs(): Promise<DefaultInfraConfig[]> {
127127
value: encrypt(randomBytes(32).toString('hex')),
128128
isEncrypted: true,
129129
},
130+
{
131+
name: InfraConfigEnum.SESSION_COOKIE_NAME,
132+
value: null,
133+
isEncrypted: false,
134+
},
130135
{
131136
name: InfraConfigEnum.TOKEN_SALT_COMPLEXITY,
132137
value: '10',

packages/hoppscotch-backend/src/infra-config/infra-config.service.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,11 @@ export class InfraConfigService implements OnModuleInit {
734734
return fail();
735735
break;
736736

737+
case InfraConfigEnum.SESSION_COOKIE_NAME:
738+
// Allow empty to fall back to default; otherwise enforce allowed characters
739+
if (value && !/^[A-Za-z0-9_-]+$/.test(value)) return fail();
740+
break;
741+
737742
default:
738743
break;
739744
}

packages/hoppscotch-backend/src/main.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,13 @@ async function bootstrap() {
4949

5050
app.use(
5151
session({
52+
// Allow overriding the default cookie name 'connect.sid' (which contains a dot).
53+
// Some proxies/load balancers (like older Kong versions) cannot hash cookie names with dots,
54+
// so we allow setting an alternative name via the INFRA.SESSION_COOKIE_NAME configuration.
55+
name:
56+
configService.get<string>('INFRA.SESSION_COOKIE_NAME') || 'connect.sid',
5257
secret:
53-
configService.get('INFRA.SESSION_SECRET') ||
58+
configService.get<string>('INFRA.SESSION_SECRET') ||
5459
crypto.randomBytes(16).toString('hex'),
5560
}),
5661
);

packages/hoppscotch-backend/src/types/InfraConfig.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export enum InfraConfigEnum {
44

55
JWT_SECRET = 'JWT_SECRET',
66
SESSION_SECRET = 'SESSION_SECRET',
7+
SESSION_COOKIE_NAME = 'SESSION_COOKIE_NAME',
78
TOKEN_SALT_COMPLEXITY = 'TOKEN_SALT_COMPLEXITY',
89
MAGIC_LINK_TOKEN_VALIDITY = 'MAGIC_LINK_TOKEN_VALIDITY',
910
REFRESH_TOKEN_VALIDITY = 'REFRESH_TOKEN_VALIDITY',

packages/hoppscotch-sh-admin/locales/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@
5252
"refresh_token_validity": "Refresh Token Validity (in milliseconds)",
5353
"access_token_validity": "Access Token Validity (in milliseconds)",
5454
"session_secret": "Session Secret",
55+
"session_cookie_name": "Session Cookie Name (optional)",
56+
"session_cookie_name_help": "Only letters, numbers, underscore, and hyphen. Leave empty to use default 'connect.sid'.",
57+
"session_cookie_name_invalid": "Invalid cookie name. Only letters, numbers, underscore, and hyphen allowed.",
5558
"update_failure": "Failed to update token configurations!!"
5659
},
5760
"update_failure": "Failed to update authentication provider configurations!!"

packages/hoppscotch-sh-admin/src/components/settings/AuthToken.vue

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,20 @@
133133
</template>
134134
</HoppSmartInput>
135135
</div>
136+
<div class="flex flex-col space-y-2">
137+
<label>{{
138+
t('configs.auth_providers.token.session_cookie_name')
139+
}}</label>
140+
<HoppSmartInput
141+
v-model="authTokenConfig.fields.session_cookie_name"
142+
placeholder="e.g., connect_sid"
143+
:autofocus="false"
144+
class="!my-2 !bg-primaryLight flex-1 border border-divider rounded"
145+
/>
146+
<p class="my-1 text-secondaryLight">
147+
{{ t('configs.auth_providers.token.session_cookie_name_help') }}
148+
</p>
149+
</div>
136150
</div>
137151
</div>
138152
</div>

packages/hoppscotch-sh-admin/src/composables/useConfigHandler.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,19 @@ import {
2828
MICROSOFT_CONFIGS,
2929
MOCK_SERVER_CONFIGS,
3030
ServerConfigs,
31+
TOKEN_VALIDATION_CONFIGS,
3132
UpdatedConfigs,
3233
} from '~/helpers/configs';
3334
import { getCompiledErrorMessage } from '~/helpers/errors';
3435
import { useToast } from './toast';
3536
import { useClientHandler } from './useClientHandler';
3637

38+
const COOKIE_NAME_REGEX = /^[A-Za-z0-9_-]+$/;
39+
40+
const OPTIONAL_TOKEN_FIELD_KEYS = new Set(
41+
TOKEN_VALIDATION_CONFIGS.filter((cfg) => cfg.optional).map((cfg) => cfg.key)
42+
);
43+
3744
/** Composable that handles all operations related to server configurations
3845
* @param updatedConfigs A Config Object containing the updated configs
3946
*/
@@ -154,6 +161,7 @@ export function useConfigHandler(updatedConfigs?: ServerConfigs) {
154161
InfraConfigEnum.AccessTokenValidity
155162
),
156163
session_secret: getFieldValue(InfraConfigEnum.SessionSecret),
164+
session_cookie_name: getFieldValue(InfraConfigEnum.SessionCookieName),
157165
},
158166
},
159167
dataSharingConfigs: {
@@ -286,8 +294,12 @@ export function useConfigHandler(updatedConfigs?: ServerConfigs) {
286294

287295
// This section has no enabled property, so we check fields directly
288296
// for a valid number (>0) or non-empty string
289-
if (section.name === 'token')
290-
return Object.values(section.fields).some(isFieldNotValid);
297+
if (section.name === 'token') {
298+
return Object.entries(section.fields).some(
299+
([key, value]) =>
300+
!OPTIONAL_TOKEN_FIELD_KEYS.has(key) && isFieldNotValid(value)
301+
);
302+
}
291303

292304
// For rate limit section, we want to check if the values are not valid numbers
293305
// and not empty strings
@@ -573,6 +585,14 @@ export function useConfigHandler(updatedConfigs?: ServerConfigs) {
573585
const sessionSecret = String(
574586
updatedConfigs?.tokenConfigs.fields.session_secret
575587
);
588+
const sessionCookieName = String(
589+
updatedConfigs?.tokenConfigs.fields.session_cookie_name || ''
590+
);
591+
// Validate cookie name: allow empty (falls back to default), else enforce pattern
592+
if (sessionCookieName && !COOKIE_NAME_REGEX.test(sessionCookieName)) {
593+
toast.error(t('configs.auth_providers.token.session_cookie_name_invalid'));
594+
return false;
595+
}
576596
if (
577597
isFieldEmpty(jwtSecret) ||
578598
isFieldEmpty(tokenSaltComplexity) ||
@@ -610,6 +630,10 @@ export function useConfigHandler(updatedConfigs?: ServerConfigs) {
610630
name: InfraConfigEnum.SessionSecret,
611631
value: sessionSecret,
612632
},
633+
{
634+
name: InfraConfigEnum.SessionCookieName,
635+
value: sessionCookieName,
636+
},
613637
];
614638

615639
return executeMutation(

packages/hoppscotch-sh-admin/src/helpers/configs.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export type ServerConfigs = {
6767
refresh_token_validity: string;
6868
access_token_validity: string;
6969
session_secret: string;
70+
session_cookie_name: string;
7071
};
7172
};
7273

@@ -116,6 +117,8 @@ export type ConfigSection = {
116117
export type Config = {
117118
name: InfraConfigEnum;
118119
key: string;
120+
// Marks fields that are optional and should be excluded from mandatory validation
121+
optional?: boolean;
119122
};
120123

121124
export const GOOGLE_CONFIGS: Config[] = [
@@ -258,6 +261,11 @@ export const TOKEN_VALIDATION_CONFIGS: Config[] = [
258261
name: InfraConfigEnum.SessionSecret,
259262
key: 'session_secret',
260263
},
264+
{
265+
name: InfraConfigEnum.SessionCookieName,
266+
key: 'session_cookie_name',
267+
optional: true,
268+
},
261269
{
262270
name: InfraConfigEnum.TokenSaltComplexity,
263271
key: 'token_salt_complexity',

0 commit comments

Comments
 (0)