Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion app/Http/Controllers/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
namespace Expose\Client\Http\Controllers;

use Expose\Client\Client;
use Expose\Client\Configuration;
use Expose\Common\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Ratchet\ConnectionInterface;

class DashboardController extends Controller
{
public function __construct(protected Configuration $configuration)
{
}

public function handle(Request $request, ConnectionInterface $httpConnection)
{
$httpConnection->send(respond_html(
Expand All @@ -17,7 +22,9 @@ public function handle(Request $request, ConnectionInterface $httpConnection)
'user' => Client::$user,
'subdomains' => Client::$subdomains,
'max_logs' => config()->get('expose.max_logged_requests', 10),
'local_url' => Client::$localUrl
'local_url' => Client::$localUrl,
'auth_token' => $this->configuration->auth(),
'platform_url' => config('expose.platform_url', 'https://expose.dev'),
],

'jsFile' => $this->getJsFilePath(),
Expand Down

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/build/internal-dashboard/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Expose Dashboard</title>
<script type="module" crossorigin src="/assets/index-DzCzO36U.js"></script>
<script type="module" crossorigin src="/assets/index-DGwMJMlj.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DXNXn6zH.css">
</head>
<body>
Expand Down
72 changes: 66 additions & 6 deletions resources/js/internal-dashboard/src/InternalDashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,80 @@ const page: InternalDashboardPageData = {
user: props.pageData?.user ?? exampleUser(),
max_logs: props.pageData?.max_logs ?? 100,
local_url: props.pageData?.local_url ?? 'http://localhost',
auth_token: props.pageData?.auth_token,
platform_url: props.pageData?.platform_url ?? 'https://expose.dev',
};

const fallbackBanner: BannerData = {
message: 'You are currently using the free version of Expose.',
cta_text: 'Upgrade to Expose Pro',
cta_url: 'https://expose.dev/get-pro',
cta_suffix: 'to get access to our fast global network, custom domains, infinite tunnel duration and more.',
background_color: 'bg-pink-600',
text_color: 'text-white',
background_style: '#db2777',
text_style: '#ffffff',
};

const bannerStyle = computed(() => {
if (!banner.value) return {};
return {
backgroundColor: banner.value.background_style,
color: banner.value.text_style,
};
});

const currentLog = ref(null as ExposeLog | null)
const search = ref('' as string)
const header = ref()
const sidebar = ref()
const qrCodeModal = ref()
const modifiedReplayModal = ref()
const banner = ref<BannerData | null>(null)

const fetchBanner = async () => {
if (!page.auth_token || !page.platform_url) {
// No token available, use fallback for free users
if (!page.user.can_specify_subdomains) {
banner.value = fallbackBanner;
}
return;
}

try {
const response = await fetch(`${page.platform_url}/api/client/banner`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify({ token: page.auth_token }),
});

if (response.ok) {
const data = await response.json();
banner.value = data.data?.banner ?? null;
} else {
// API error, use fallback for free users
if (!page.user.can_specify_subdomains) {
banner.value = fallbackBanner;
}
}
} catch (error) {
// Network error, use fallback for free users
if (!page.user.can_specify_subdomains) {
banner.value = fallbackBanner;
}
}
};

onMounted(() => {
window.addEventListener('keydown', setupKeybindings);

const pageTitle = 'Sharing ' + page.local_url.substring(page.local_url.indexOf('://') + 3) + ' - Expose';
document.title = pageTitle;

fetchBanner();
});

const setLog = (log: ExposeLog | null) => {
Expand Down Expand Up @@ -84,19 +144,19 @@ const setupKeybindings = (event: KeyboardEvent) => {
}

const siteHeight = computed(() => {
return page.user.can_specify_subdomains ? 'h-[calc(100vh-81px)]' : 'h-[calc(100vh-160px)]';
return banner.value ? 'h-[calc(100vh-160px)]' : 'h-[calc(100vh-81px)]';
})

</script>

<template>
<div class="mx-auto h-screen overflow-hidden min-[2000px]:border-l min-[2000px]:border-r">
<div v-if="!page.user.can_specify_subdomains"
class="py-2 px-4 bg-pink-600 flex flex-col items-center justify-center text-white font-medium text-lg text-center">
<p>You are currently using the free version of Expose.</p>
<div v-if="banner"
:class="[banner.background_color, banner.text_color, 'py-2 px-4 flex flex-col items-center justify-center font-medium text-lg text-center']"
:style="bannerStyle">
<p>{{ banner.message }}</p>
<p class="font-bold">
<a href="https://expose.dev/get-pro" class="underline">Upgrade to Expose
Pro</a> to get access to our fast global network, custom domains, infinite tunnel duration and more.
<a :href="banner.cta_url" class="underline">{{ banner.cta_text }}</a> {{ banner.cta_suffix }}
</p>
</div>
<div class="h-full">
Expand Down
13 changes: 13 additions & 0 deletions resources/js/internal-dashboard/src/types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,19 @@ declare interface RequestData {
user: ExposeUser;
max_logs: number;
local_url: string;
auth_token?: string;
platform_url?: string;
}

interface BannerData {
message: string;
cta_text: string;
cta_url: string;
cta_suffix: string;
background_color: string;
text_color: string;
background_style?: string;
text_style?: string;
}

interface ExposeUser {
Expand Down