fix(staff): fix staff/me profile resolution and add POS access
Root cause: BFF GetMyStaffProfile used ExtractUserIdFromJwt(authHeader) which reads Authorization header — but BFF uses httpOnly cookie auth, so authHeader was always null → userId match always failed → 404. Fix: Extract userId/email from bff_session cookie instead. Also add email fallback matching when userId match fails. Additionally: - Add "Mở POS" button on Staff Dashboard (orange, links to POS page) - Add "Mở POS" link in StaffLayout sidebar for Cashier/Manager roles - POS link uses shopId from staff's shopAssignment Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -57,11 +57,11 @@
|
||||
<span>Bàn / Order</span>
|
||||
</NavLink>
|
||||
}
|
||||
@if (_staffRole == "Cashier")
|
||||
@if (_staffRole == "Cashier" || _staffRole == "Manager")
|
||||
{
|
||||
<NavLink href="/staff/pos" class="staff-nav-item" ActiveClass="staff-nav-item--active">
|
||||
<NavLink href="@(_shopId.HasValue ? $"/pos/{_shopId}/cafe" : "/staff/pos")" class="staff-nav-item" ActiveClass="staff-nav-item--active">
|
||||
<i data-lucide="monitor"></i>
|
||||
<span>Thu ngân</span>
|
||||
<span>Mở POS</span>
|
||||
</NavLink>
|
||||
}
|
||||
@if (_staffRole == "Manager")
|
||||
|
||||
@@ -46,6 +46,14 @@
|
||||
<i data-lucide="calendar-off"></i>
|
||||
Xin nghỉ phép
|
||||
</button>
|
||||
|
||||
@if (_profile?.ShopId.HasValue == true)
|
||||
{
|
||||
<button class="staff-btn-primary" style="background:#FF5C00;" @onclick="@(() => Nav.NavigateTo($"/pos/{_profile.ShopId}/cafe"))">
|
||||
<i data-lucide="monitor"></i>
|
||||
Mở POS
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
|
||||
@* ═══ STAT CARDS ═══ *@
|
||||
|
||||
@@ -170,8 +170,13 @@ public class StaffController : ControllerBase
|
||||
public async Task<IActionResult> GetMyStaffProfile()
|
||||
{
|
||||
// EN: Get all staff for this merchant — AuthForwardingHandler auto-forwards the Bearer token.
|
||||
// Fallback: if merchant-service rejects (staff user is not owner), try staff lookup by email.
|
||||
// VI: Lấy tất cả nhân viên của merchant — AuthForwardingHandler tự động chuyển tiếp Bearer token.
|
||||
// Fallback: nếu merchant-service từ chối (staff user không phải owner), thử tìm theo email.
|
||||
var authHeader = Request.Headers["Authorization"].FirstOrDefault();
|
||||
var (currentUserId, currentEmail) = ExtractUserClaimsFromJwt(
|
||||
Request.Cookies.TryGetValue("bff_session", out var cookie) ? $"Bearer {cookie}" : authHeader);
|
||||
|
||||
var staffResp = await _merchant.GetAsync("/api/v1/merchants/me/staff");
|
||||
if (!staffResp.IsSuccessStatusCode)
|
||||
return StatusCode((int)staffResp.StatusCode, await staffResp.Content.ReadAsStringAsync());
|
||||
@@ -191,9 +196,11 @@ public class StaffController : ControllerBase
|
||||
else
|
||||
return NotFound(new { success = false, message = "No staff data found" });
|
||||
|
||||
// EN: Extract userId from JWT 'sub' claim to match staff by userId.
|
||||
// VI: Trích userId từ JWT 'sub' claim để match nhân viên theo userId.
|
||||
var userId = ExtractUserIdFromJwt(authHeader);
|
||||
// EN: Use userId + email already extracted from session cookie (line 177-178).
|
||||
// Previous bug: ExtractUserIdFromJwt(authHeader) used Authorization header which is null for cookie-based BFF auth.
|
||||
// VI: Dùng userId + email đã extract từ session cookie (dòng 177-178).
|
||||
// Bug trước: ExtractUserIdFromJwt(authHeader) dùng Authorization header mà null khi dùng cookie-based BFF auth.
|
||||
var userId = currentUserId;
|
||||
|
||||
// EN: Find matching staff member by userId, then by email fallback
|
||||
// VI: Tìm nhân viên khớp theo userId, fallback theo email
|
||||
@@ -211,6 +218,21 @@ public class StaffController : ControllerBase
|
||||
}
|
||||
}
|
||||
|
||||
// EN: Fallback: match by email if userId match failed
|
||||
// VI: Fallback: match theo email nếu userId không khớp
|
||||
if (matchedStaff == null && !string.IsNullOrEmpty(currentEmail) && items.ValueKind == JsonValueKind.Array)
|
||||
{
|
||||
foreach (var staff in items.EnumerateArray())
|
||||
{
|
||||
if (staff.TryGetProperty("email", out var emailProp) &&
|
||||
string.Equals(emailProp.GetString(), currentEmail, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
matchedStaff = staff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (matchedStaff == null)
|
||||
return NotFound(new { success = false, message = "Staff profile not found for current user" });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user