From deee4fd052e91214464b3b6fc1809086e13ca794 Mon Sep 17 00:00:00 2001 From: kastov Date: Sat, 20 Dec 2025 20:59:37 +0300 Subject: [PATCH 1/9] fix: enhance error logging --- backend/src/common/axios/axios.service.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/backend/src/common/axios/axios.service.ts b/backend/src/common/axios/axios.service.ts index 21efdf9..23aae38 100644 --- a/backend/src/common/axios/axios.service.ts +++ b/backend/src/common/axios/axios.service.ts @@ -203,11 +203,13 @@ export class AxiosService implements OnModuleInit { ); return { isOk: false }; } - } - - this.logger.error('Error in GetSubscriptionPageConfigList Request:', error); - return { isOk: false }; + this.logger.error(`Subpage Config List Request failed: ${error.message}`); + return { isOk: false }; + } else { + this.logger.error(`Subpage Config List Request failed: ${error}`); + return { isOk: false }; + } } } From 1e599e4a3786974d6cfeef3a45ee7d9499751703 Mon Sep 17 00:00:00 2001 From: kastov Date: Sat, 20 Dec 2025 21:48:25 +0300 Subject: [PATCH 2/9] feat: strict response validation --- backend/src/common/axios/axios.service.ts | 9 +++++++-- backend/src/common/config/app-config/config.schema.ts | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/backend/src/common/axios/axios.service.ts b/backend/src/common/axios/axios.service.ts index 23aae38..4ced623 100644 --- a/backend/src/common/axios/axios.service.ts +++ b/backend/src/common/axios/axios.service.ts @@ -102,11 +102,13 @@ export class AxiosService implements OnModuleInit { error?: unknown; }> { try { - await this.axiosInstance.request({ + const response = await this.axiosInstance.request({ method: GetStatusCommand.endpointDetails.REQUEST_METHOD, url: GetStatusCommand.TSQ_url, }); + await GetStatusCommand.ResponseSchema.parseAsync(response.data); + return { isOk: true, }; @@ -190,9 +192,12 @@ export class AxiosService implements OnModuleInit { url: GetSubscriptionPageConfigsCommand.url, }); + const validationResult = + await GetSubscriptionPageConfigsCommand.ResponseSchema.parseAsync(response.data); + return { isOk: true, - response: response.data.response, + response: validationResult.response, }; } catch (error) { if (error instanceof AxiosError) { diff --git a/backend/src/common/config/app-config/config.schema.ts b/backend/src/common/config/app-config/config.schema.ts index 63194f7..ceae033 100644 --- a/backend/src/common/config/app-config/config.schema.ts +++ b/backend/src/common/config/app-config/config.schema.ts @@ -28,6 +28,7 @@ export const configSchema = z .transform((val) => val === 'true'), MARZBAN_LEGACY_SECRET_KEY: z.optional(z.string()), MARZBAN_LEGACY_SUBSCRIPTION_VALID_FROM: z.optional(z.string()), + INTERNAL_JWT_SECRET: z.string(), }) .superRefine((data, ctx) => { if ( From 22dc1ad37e87e824640d7ac17b323e4d62b44248 Mon Sep 17 00:00:00 2001 From: kastov Date: Sat, 20 Dec 2025 21:51:18 +0300 Subject: [PATCH 3/9] chore: bump version to 7.0.5 in package.json and package-lock.json for frontend and backend --- backend/package-lock.json | 4 ++-- backend/package.json | 2 +- frontend/package-lock.json | 4 ++-- frontend/package.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index b50488c..f994142 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1,12 +1,12 @@ { "name": "@remnawave/subscription-page", - "version": "7.0.4", + "version": "7.0.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@remnawave/subscription-page", - "version": "7.0.4", + "version": "7.0.5", "license": "AGPL-3.0-only", "dependencies": { "@kastov/request-ip": "^0.0.5", diff --git a/backend/package.json b/backend/package.json index f14a62f..75b8bc8 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "@remnawave/subscription-page", - "version": "7.0.4", + "version": "7.0.5", "description": "Remnawave Subscription Page", "private": false, "type": "commonjs", diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ac531be..dfbcdb2 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "@remnawave/subscription-page", - "version": "7.0.4", + "version": "7.0.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@remnawave/subscription-page", - "version": "7.0.4", + "version": "7.0.5", "license": "AGPL-3.0-only", "dependencies": { "@gfazioli/mantine-spinner": "^2.3.9", diff --git a/frontend/package.json b/frontend/package.json index 68b9e2c..f7ddb17 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -2,7 +2,7 @@ "name": "@remnawave/subscription-page", "private": false, "type": "module", - "version": "7.0.4", + "version": "7.0.5", "license": "AGPL-3.0-only", "author": "REMNAWAVE ", "homepage": "https://github.com/remnawave", From d0c485c6634fcb3059ae6b078b71f93f307375f7 Mon Sep 17 00:00:00 2001 From: kastov Date: Sat, 20 Dec 2025 23:19:27 +0300 Subject: [PATCH 4/9] refactor: improve subpage configuration retrieval logic --- backend/src/modules/root/subpage-config.service.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/backend/src/modules/root/subpage-config.service.ts b/backend/src/modules/root/subpage-config.service.ts index 936dc2c..3d8fbbe 100644 --- a/backend/src/modules/root/subpage-config.service.ts +++ b/backend/src/modules/root/subpage-config.service.ts @@ -122,9 +122,17 @@ export class SubpageConfigService implements OnApplicationBootstrap { public getBaseSettings( subpageConfigUuid: string | null, ): TSubscriptionPageRawConfig['baseSettings'] { - const subpageConfig = this.subpageConfigMap.get( - subpageConfigUuid || SUBPAGE_DEFAULT_CONFIG_UUID, - ); + let finalSubpageConfigUuid: string; + + const isDefaultUuid = this.subpageConfigUuid === SUBPAGE_DEFAULT_CONFIG_UUID; + + if (isDefaultUuid && subpageConfigUuid) { + finalSubpageConfigUuid = subpageConfigUuid; + } else { + finalSubpageConfigUuid = this.subpageConfigUuid; + } + + const subpageConfig = this.subpageConfigMap.get(finalSubpageConfigUuid); if (!subpageConfig) { return { From c4219e48ccb7f50209c19a0b0f13f15fb4e3b421 Mon Sep 17 00:00:00 2001 From: kastov Date: Sat, 20 Dec 2025 23:21:23 +0300 Subject: [PATCH 5/9] refactor: streamline UUID encryption and configuration retrieval in SubpageConfigService --- .../modules/root/subpage-config.service.ts | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/backend/src/modules/root/subpage-config.service.ts b/backend/src/modules/root/subpage-config.service.ts index 3d8fbbe..2057ea0 100644 --- a/backend/src/modules/root/subpage-config.service.ts +++ b/backend/src/modules/root/subpage-config.service.ts @@ -106,33 +106,18 @@ export class SubpageConfigService implements OnApplicationBootstrap { } public getEncryptedSubpageConfigUuid(subpageConfigUuidFromRemnawave: string | null): string { - let uuidToEncrypt: string; - - const isDefaultUuid = this.subpageConfigUuid === SUBPAGE_DEFAULT_CONFIG_UUID; - - if (isDefaultUuid && subpageConfigUuidFromRemnawave) { - uuidToEncrypt = subpageConfigUuidFromRemnawave; - } else { - uuidToEncrypt = this.subpageConfigUuid; - } - - return encryptUuid(uuidToEncrypt, this.internalJwtSecret); + return encryptUuid( + this.getFinalSubpageConfigUuid(subpageConfigUuidFromRemnawave), + this.internalJwtSecret, + ); } public getBaseSettings( subpageConfigUuid: string | null, ): TSubscriptionPageRawConfig['baseSettings'] { - let finalSubpageConfigUuid: string; - - const isDefaultUuid = this.subpageConfigUuid === SUBPAGE_DEFAULT_CONFIG_UUID; - - if (isDefaultUuid && subpageConfigUuid) { - finalSubpageConfigUuid = subpageConfigUuid; - } else { - finalSubpageConfigUuid = this.subpageConfigUuid; - } - - const subpageConfig = this.subpageConfigMap.get(finalSubpageConfigUuid); + const subpageConfig = this.subpageConfigMap.get( + this.getFinalSubpageConfigUuid(subpageConfigUuid), + ); if (!subpageConfig) { return { @@ -148,4 +133,18 @@ export class SubpageConfigService implements OnApplicationBootstrap { showConnectionKeys: subpageConfig.baseSettings.showConnectionKeys, }; } + + private getFinalSubpageConfigUuid(subpageConfigUuid: string | null): string { + let finalSubpageConfigUuid: string; + + const isDefaultUuid = this.subpageConfigUuid === SUBPAGE_DEFAULT_CONFIG_UUID; + + if (isDefaultUuid && subpageConfigUuid) { + finalSubpageConfigUuid = subpageConfigUuid; + } else { + finalSubpageConfigUuid = this.subpageConfigUuid; + } + + return finalSubpageConfigUuid; + } } From 8780fbc0892656f54affc67c81c9d1c6fd71674a Mon Sep 17 00:00:00 2001 From: kastov Date: Sun, 21 Dec 2025 07:23:41 +0300 Subject: [PATCH 6/9] feat: app icons --- .../installation-guide.connector.tsx | 58 ++++++--- .../installation-guide.module.css | 114 ++++++++++++++++-- 2 files changed, 141 insertions(+), 31 deletions(-) diff --git a/frontend/src/widgets/main/installation-guide/installation-guide.connector.tsx b/frontend/src/widgets/main/installation-guide/installation-guide.connector.tsx index 4943a18..fe53d0f 100644 --- a/frontend/src/widgets/main/installation-guide/installation-guide.connector.tsx +++ b/frontend/src/widgets/main/installation-guide/installation-guide.connector.tsx @@ -3,11 +3,21 @@ import { TSubscriptionPageButtonConfig, TSubscriptionPagePlatformKey } from '@remnawave/subscription-page-types' -import { Box, Button, ButtonVariant, Card, Group, NativeSelect, Stack, Title } from '@mantine/core' +import { + Box, + Button, + ButtonVariant, + Card, + Group, + NativeSelect, + Stack, + Title, + UnstyledButton +} from '@mantine/core' import { notifications } from '@mantine/notifications' -import { IconStar } from '@tabler/icons-react' import { useClipboard } from '@mantine/hooks' import { useState } from 'react' +import clsx from 'clsx' import { constructSubscriptionUrl } from '@shared/utils/construct-subscription-url' import { useSubscription } from '@entities/subscription-info-store' @@ -186,34 +196,44 @@ export const InstallationGuideConnector = (props: IProps) => { {platformApps.length > 0 && ( - +
{platformApps.map((app: TSubscriptionPageAppConfig, index: number) => { const isActive = index === selectedAppIndex + const hasIcon = Boolean(app.svgIconKey) + return ( - + {app.featured && } + {hasIcon && ( + + )} + {app.name} + ) })} - +
{selectedApp && ( Date: Sun, 21 Dec 2025 08:34:02 +0300 Subject: [PATCH 7/9] fix: adjust transition duration --- .../subscription-info-collapsed.widget.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/widgets/main/subscription-info/subscription-info-collapsed.widget.tsx b/frontend/src/widgets/main/subscription-info/subscription-info-collapsed.widget.tsx index bc44a30..734b594 100644 --- a/frontend/src/widgets/main/subscription-info/subscription-info-collapsed.widget.tsx +++ b/frontend/src/widgets/main/subscription-info/subscription-info-collapsed.widget.tsx @@ -108,15 +108,15 @@ export const SubscriptionInfoCollapsedWidget = ({ isMobile }: IProps) => { color="var(--mantine-color-dimmed)" size={18} style={{ - transition: 'transform 200ms ease', - transform: isExpanded ? 'rotate(180deg)' : 'rotate(0deg)' + transform: isExpanded ? 'rotate(180deg)' : 'rotate(0deg)', + transition: 'transform 150ms ease' }} />
- + Date: Sun, 21 Dec 2025 09:34:00 +0300 Subject: [PATCH 8/9] fix: update logo dimensions --- .../src/pages/main/ui/components/main.page.component.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/frontend/src/pages/main/ui/components/main.page.component.tsx b/frontend/src/pages/main/ui/components/main.page.component.tsx index 0f4ebad..4317cc5 100644 --- a/frontend/src/pages/main/ui/components/main.page.component.tsx +++ b/frontend/src/pages/main/ui/components/main.page.component.tsx @@ -77,10 +77,9 @@ export const MainPageComponent = ({ isMobile, platform }: IMainPageComponentProp fit="contain" src={config.brandingSettings.logoUrl} style={{ - maxWidth: '32px', - maxHeight: '32px', - width: 'auto', - height: 'auto' + width: '32px', + height: '32px', + flexShrink: 0 }} /> ) : ( From 8c59e30866bea6ad99954b9b740a9f1700b890c1 Mon Sep 17 00:00:00 2001 From: kastov Date: Sun, 21 Dec 2025 09:42:47 +0300 Subject: [PATCH 9/9] refactor: simplify layout structure and improve styling in main page component --- .../ui/components/main.page.component.tsx | 21 +++++++++---------- .../subscription-link.widget.tsx | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/frontend/src/pages/main/ui/components/main.page.component.tsx b/frontend/src/pages/main/ui/components/main.page.component.tsx index 4317cc5..38dfc3e 100644 --- a/frontend/src/pages/main/ui/components/main.page.component.tsx +++ b/frontend/src/pages/main/ui/components/main.page.component.tsx @@ -1,4 +1,4 @@ -import { Box, Center, Container, Group, Image, Stack, Text, Title } from '@mantine/core' +import { Box, Center, Container, Group, Image, Stack, Title } from '@mantine/core' import { TSubscriptionPagePlatformKey } from '@remnawave/subscription-page-types' import { @@ -69,7 +69,7 @@ export const MainPageComponent = ({ isMobile, platform }: IMainPageComponentProp - + {hasCustomLogo ? ( )} - - <Text c={hasCustomLogo ? 'white' : 'cyan'} component="span" inherit> - {brandName} - </Text> + <Title + c={hasCustomLogo ? 'white' : 'cyan'} + fw={700} + order={4} + size="lg" + > + {brandName} - - - + diff --git a/frontend/src/widgets/main/subscription-link/subscription-link.widget.tsx b/frontend/src/widgets/main/subscription-link/subscription-link.widget.tsx index 3f38dea..b9cee15 100644 --- a/frontend/src/widgets/main/subscription-link/subscription-link.widget.tsx +++ b/frontend/src/widgets/main/subscription-link/subscription-link.widget.tsx @@ -121,7 +121,7 @@ export const SubscriptionLinkWidget = ({ supportUrl }: IProps) => { } return ( - +