feat: Add PublicBotsController for anonymous ShareCard access
All checks were successful
Build and Deploy LittleShop / Deploy to Production VPS (Manual Only) (push) Has been skipped
Build and Deploy LittleShop / Deploy to Pre-Production (CT109) (push) Successful in 1m5s

- Created PublicBotsController with [AllowAnonymous] at class level
  to avoid policy authorization conflicts with the main BotsController
- Updated ShareCard.cshtml to use PublicBots controller for embed links
- Fixes HTTP 500 error when accessing ShareCard without authentication

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
SysAdmin 2025-12-01 23:30:12 +00:00
parent 646ecf77ee
commit 996f207c48
2 changed files with 69 additions and 3 deletions

View File

@ -0,0 +1,66 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using LittleShop.Services;
namespace LittleShop.Areas.Admin.Controllers;
/// <summary>
/// Public-facing bot pages that don't require authentication.
/// These are separated from the main BotsController to avoid authorization conflicts.
/// </summary>
[Area("Admin")]
[AllowAnonymous]
public class PublicBotsController : Controller
{
private readonly IBotService _botService;
public PublicBotsController(IBotService botService)
{
_botService = botService;
}
// GET: Admin/PublicBots/ShareCard/5
public async Task<IActionResult> ShareCard(Guid id)
{
var bot = await _botService.GetBotByIdAsync(id);
if (bot == null)
return NotFound();
// Build the tg.me link
var telegramLink = !string.IsNullOrEmpty(bot.PlatformUsername)
? $"https://t.me/{bot.PlatformUsername}"
: null;
ViewData["TelegramLink"] = telegramLink;
// Get review stats (TODO: Replace with actual review data from database)
// For now using sample data - in production, query from Reviews table
ViewData["ReviewCount"] = 127;
ViewData["AverageRating"] = 4.8m;
return View("~/Areas/Admin/Views/Bots/ShareCard.cshtml", bot);
}
// GET: Admin/PublicBots/ShareCardEmbed/5
public async Task<IActionResult> ShareCardEmbed(Guid id)
{
var bot = await _botService.GetBotByIdAsync(id);
if (bot == null)
return NotFound();
// Build the tg.me link
var telegramLink = !string.IsNullOrEmpty(bot.PlatformUsername)
? $"https://t.me/{bot.PlatformUsername}"
: null;
ViewData["TelegramLink"] = telegramLink;
// Get review stats
ViewData["ReviewCount"] = 127;
ViewData["AverageRating"] = 4.8m;
return View("~/Areas/Admin/Views/Bots/ShareCardEmbed.cshtml", bot);
}
}

View File

@ -446,7 +446,7 @@
<a href="@Url.Action("Details", "Bots", new { area = "Admin", id = Model.Id })" class="btn btn-outline-secondary"> <a href="@Url.Action("Details", "Bots", new { area = "Admin", id = Model.Id })" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left"></i> Back to Details <i class="fas fa-arrow-left"></i> Back to Details
</a> </a>
<a href="@Url.Action("ShareCardEmbed", "Bots", new { area = "Admin", id = Model.Id })" target="_blank" class="btn btn-outline-success ms-2"> <a href="@Url.Action("ShareCardEmbed", "PublicBots", new { area = "Admin", id = Model.Id })" target="_blank" class="btn btn-outline-success ms-2">
<i class="fas fa-external-link-alt"></i> View Public Card <i class="fas fa-external-link-alt"></i> View Public Card
</a> </a>
<button type="button" class="btn btn-outline-primary ms-2" onclick="showEmbedModal()"> <button type="button" class="btn btn-outline-primary ms-2" onclick="showEmbedModal()">
@ -466,14 +466,14 @@
<p class="text-muted">Copy this code to embed the share card on your website:</p> <p class="text-muted">Copy this code to embed the share card on your website:</p>
<div class="mb-3"> <div class="mb-3">
<label class="form-label fw-bold">IFrame Embed</label> <label class="form-label fw-bold">IFrame Embed</label>
<textarea class="form-control font-monospace" rows="4" readonly id="embedCode">&lt;iframe src="@Url.Action("ShareCardEmbed", "Bots", new { area = "Admin", id = Model.Id }, Context.Request.Scheme)" width="450" height="750" frameborder="0" style="border-radius: 20px; overflow: hidden;"&gt;&lt;/iframe&gt;</textarea> <textarea class="form-control font-monospace" rows="4" readonly id="embedCode">&lt;iframe src="@Url.Action("ShareCardEmbed", "PublicBots", new { area = "Admin", id = Model.Id }, Context.Request.Scheme)" width="450" height="750" frameborder="0" style="border-radius: 20px; overflow: hidden;"&gt;&lt;/iframe&gt;</textarea>
<button class="btn btn-sm btn-outline-secondary mt-2" onclick="copyEmbedCode()"> <button class="btn btn-sm btn-outline-secondary mt-2" onclick="copyEmbedCode()">
<i class="fas fa-copy"></i> Copy Code <i class="fas fa-copy"></i> Copy Code
</button> </button>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label class="form-label fw-bold">Direct Link</label> <label class="form-label fw-bold">Direct Link</label>
<input type="text" class="form-control font-monospace" readonly id="directLink" value="@Url.Action("ShareCardEmbed", "Bots", new { area = "Admin", id = Model.Id }, Context.Request.Scheme)" /> <input type="text" class="form-control font-monospace" readonly id="directLink" value="@Url.Action("ShareCardEmbed", "PublicBots", new { area = "Admin", id = Model.Id }, Context.Request.Scheme)" />
<button class="btn btn-sm btn-outline-secondary mt-2" onclick="copyDirectLink()"> <button class="btn btn-sm btn-outline-secondary mt-2" onclick="copyDirectLink()">
<i class="fas fa-copy"></i> Copy Link <i class="fas fa-copy"></i> Copy Link
</button> </button>