Skip to content

Commit aa72aff

Browse files
authored
Merge pull request #65 from Liwyd/fix_marzban_sub
Fix: Improve subscription link generation to prevent duplicate path
2 parents d37642b + 3ea8385 commit aa72aff

File tree

2 files changed

+11
-7
lines changed

2 files changed

+11
-7
lines changed

frontend/src/lib/api.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ function generateSubId(): string {
181181
for (let i = 0; i < 8; i++) {
182182
result += chars.charAt(Math.floor(Math.random() * chars.length))
183183
}
184-
return result
184+
// Ensure no leading or trailing slashes
185+
return result.replace(/^\/+|\/+$/g, '')
185186
}
186187

187188
// User API
@@ -216,12 +217,15 @@ export const userAPI = {
216217
flow: string = '',
217218
userId?: string
218219
): Promise<ClientsOutput> => {
220+
// Sanitize sub_id to remove leading and trailing slashes to prevent double slashes in subscription URL
221+
const sanitizedSubId = subId?.replace(/^\/+|\/+$/g, '') || '';
222+
219223
const submitData = {
220224
email,
221225
enable,
222226
expiry_time: expiryDatetime ? new Date(expiryDatetime + 'T00:00:00').getTime() : 0,
223227
total: Math.floor(totalGb * 1024 * 1024 * 1024),
224-
sub_id: subId,
228+
sub_id: sanitizedSubId,
225229
flow,
226230
}
227231

frontend/src/pages/DashboardPage.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ export function DashboardPage() {
589589
<>
590590
<div className="p-4 bg-white rounded-lg border">
591591
<QRCodeSVG
592-
value={`${dashboardData.sub_url}/${qrUser.sub_id?.replace('/', '')}`}
592+
value={`${dashboardData.sub_url}/${qrUser.sub_id?.replace(/^\/+|\/+$/g, '')}`}
593593
size={200}
594594
level="M"
595595
/>
@@ -599,7 +599,7 @@ export function DashboardPage() {
599599
<p><strong>User:</strong> {qrUser?.username}</p>
600600
</div>
601601
<div className="p-3 bg-muted rounded-md break-all text-xs font-mono">
602-
{`${dashboardData.sub_url}/${qrUser.sub_id?.replace('/', '')}`}
602+
{`${dashboardData.sub_url}/${qrUser.sub_id?.replace(new RegExp(`^${dashboardData.sub_url.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`), '').replace(/^\/+/, '')}`}
603603
</div>
604604
</div>
605605
</>
@@ -720,7 +720,7 @@ function DetailsRow({
720720
{subUrl && user.sub_id && (
721721
<div className="p-3 bg-background rounded-md border">
722722
<div className="text-xs text-muted-foreground mb-1">Subscription Link:</div>
723-
<div className="text-xs font-mono break-all">{`${subUrl}/${user.sub_id?.replace('/', '')}`}</div>
723+
<div className="text-xs font-mono break-all">{`${subUrl}/${user.sub_id?.replace(new RegExp(`^${subUrl.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`), '').replace(/^\/+/, '')}`}</div>
724724
</div>
725725
)}
726726
<div className="flex flex-wrap gap-2 pt-2">
@@ -737,7 +737,7 @@ function DetailsRow({
737737
size="sm"
738738
variant="outline"
739739
onClick={() => {
740-
navigator.clipboard.writeText(`${subUrl}/${user.sub_id?.replace('/', '') || user.sub_id}`)
740+
navigator.clipboard.writeText(`${subUrl}/${user.sub_id?.replace(new RegExp(`^${subUrl.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`), '').replace(/^\/+/, '') || user.sub_id}`)
741741
}}
742742
>
743743
<Copy className="h-4 w-4 mr-2" />
@@ -896,7 +896,7 @@ function MobileUserCard({
896896
className="flex-1 min-w-[80px]"
897897
onClick={(e) => {
898898
e.stopPropagation()
899-
navigator.clipboard.writeText(`${subUrl}/${user.sub_id?.replace('/', '') || user.sub_id}`)
899+
navigator.clipboard.writeText(`${subUrl}/${user.sub_id?.replace(new RegExp(`^${subUrl.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`), '').replace(/^\/+/, '') || user.sub_id}`)
900900
}}
901901
>
902902
<Copy className="h-3 w-3 mr-1" />

0 commit comments

Comments
 (0)