marriedtermiteblyi commited on
Commit
2bb5053
·
verified ·
1 Parent(s): 56179f5

Upload 3 files

Browse files
Files changed (2) hide show
  1. static/app.js +24 -0
  2. static/index.html +2 -2
static/app.js CHANGED
@@ -99,6 +99,8 @@ function hugpanel() {
99
  await this._loadZoneLimit();
100
 
101
  // Try to restore session from stored token
 
 
102
  if (this.token && this.adminApiUrl) {
103
  try {
104
  const resp = await fetch(`${this.adminApiUrl}/auth/me`, {
@@ -189,6 +191,20 @@ function hugpanel() {
189
  setTimeout(() => { this.toast.show = false; }, 3000);
190
  },
191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  // ── API Helper ──
193
  async api(url, options = {}) {
194
  try {
@@ -258,6 +274,7 @@ function hugpanel() {
258
  this.token = data.token;
259
  this.user = data.user;
260
  localStorage.setItem('hugpanel_token', data.token);
 
261
  await this._loadPanel();
262
  this.$nextTick(() => lucide.createIcons());
263
  } catch (err) {
@@ -288,6 +305,7 @@ function hugpanel() {
288
  this.token = data.token;
289
  this.user = data.user;
290
  localStorage.setItem('hugpanel_token', data.token);
 
291
  await this._loadPanel();
292
  this.$nextTick(() => lucide.createIcons());
293
  } catch (err) {
@@ -299,6 +317,7 @@ function hugpanel() {
299
  logout() {
300
  this.token = null;
301
  this.user = null;
 
302
  localStorage.removeItem('hugpanel_token');
303
  localStorage.removeItem('hugpanel_admin_url');
304
  localStorage.removeItem('hugpanel_zone');
@@ -559,6 +578,11 @@ function hugpanel() {
559
  return this.backupList.filter((item) => item.zone_name === zoneName).length;
560
  },
561
 
 
 
 
 
 
562
  async copyText(value, message = 'Đã copy') {
563
  try {
564
  await navigator.clipboard.writeText(value);
 
99
  await this._loadZoneLimit();
100
 
101
  // Try to restore session from stored token
102
+ this.syncAuthCookie();
103
+
104
  if (this.token && this.adminApiUrl) {
105
  try {
106
  const resp = await fetch(`${this.adminApiUrl}/auth/me`, {
 
191
  setTimeout(() => { this.toast.show = false; }, 3000);
192
  },
193
 
194
+ setAuthCookie(token) {
195
+ const secure = location.protocol === 'https:' ? '; Secure' : '';
196
+ document.cookie = `token=${encodeURIComponent(token)}; Path=/; SameSite=Lax${secure}`;
197
+ },
198
+
199
+ clearAuthCookie() {
200
+ document.cookie = 'token=; Path=/; Max-Age=0; SameSite=Lax';
201
+ },
202
+
203
+ syncAuthCookie() {
204
+ if (this.token) this.setAuthCookie(this.token);
205
+ else this.clearAuthCookie();
206
+ },
207
+
208
  // ── API Helper ──
209
  async api(url, options = {}) {
210
  try {
 
274
  this.token = data.token;
275
  this.user = data.user;
276
  localStorage.setItem('hugpanel_token', data.token);
277
+ this.syncAuthCookie();
278
  await this._loadPanel();
279
  this.$nextTick(() => lucide.createIcons());
280
  } catch (err) {
 
305
  this.token = data.token;
306
  this.user = data.user;
307
  localStorage.setItem('hugpanel_token', data.token);
308
+ this.syncAuthCookie();
309
  await this._loadPanel();
310
  this.$nextTick(() => lucide.createIcons());
311
  } catch (err) {
 
317
  logout() {
318
  this.token = null;
319
  this.user = null;
320
+ this.clearAuthCookie();
321
  localStorage.removeItem('hugpanel_token');
322
  localStorage.removeItem('hugpanel_admin_url');
323
  localStorage.removeItem('hugpanel_zone');
 
578
  return this.backupList.filter((item) => item.zone_name === zoneName).length;
579
  },
580
 
581
+ buildPortUrl(port) {
582
+ const base = port?.url || (`/port/${this.currentZone}/${port?.port}/`);
583
+ return new URL(base, location.origin).toString();
584
+ },
585
+
586
  async copyText(value, message = 'Đã copy') {
587
  try {
588
  await navigator.clipboard.writeText(value);
static/index.html CHANGED
@@ -499,11 +499,11 @@
499
  Port: <span x-text="port.port" class="text-gray-400 font-mono"></span>
500
  </div>
501
  </div>
502
- <button @click="copyText((location.origin || '') + (port.url || ('/port/' + currentZone + '/' + port.port + '/')), 'Đã copy link port')"
503
  class="p-2 rounded-lg text-gray-400 hover:text-cyan-400 hover:bg-cyan-400/10 transition" title="Copy link">
504
  <i data-lucide="copy" class="w-4 h-4"></i>
505
  </button>
506
- <a :href="port.url || ('/port/' + currentZone + '/' + port.port + '/')"
507
  target="_blank"
508
  class="p-2 rounded-lg text-gray-400 hover:text-brand-400 hover:bg-brand-400/10 transition" title="Mở">
509
  <i data-lucide="external-link" class="w-4 h-4"></i>
 
499
  Port: <span x-text="port.port" class="text-gray-400 font-mono"></span>
500
  </div>
501
  </div>
502
+ <button @click="copyText(buildPortUrl(port), 'Đã copy link port')"
503
  class="p-2 rounded-lg text-gray-400 hover:text-cyan-400 hover:bg-cyan-400/10 transition" title="Copy link">
504
  <i data-lucide="copy" class="w-4 h-4"></i>
505
  </button>
506
+ <a :href="buildPortUrl(port)"
507
  target="_blank"
508
  class="p-2 rounded-lg text-gray-400 hover:text-brand-400 hover:bg-brand-400/10 transition" title="Mở">
509
  <i data-lucide="external-link" class="w-4 h-4"></i>