@mohasinac/appkit 2.6.4 → 2.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/layout/DashboardLayoutClient.d.ts +8 -1
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +18 -2
- package/dist/_internal/server/features/auth/capabilities.d.ts +17 -0
- package/dist/_internal/server/features/auth/capabilities.js +31 -0
- package/dist/_internal/server/features/auth/index.d.ts +2 -0
- package/dist/_internal/server/features/auth/index.js +2 -0
- package/dist/_internal/server/features/auth/permissions.d.ts +49 -0
- package/dist/_internal/server/features/auth/permissions.js +76 -0
- package/dist/_internal/shared/features/events/schema.d.ts +4 -4
- package/dist/client.d.ts +4 -4
- package/dist/client.js +2 -2
- package/dist/configs/next.d.ts +6 -1
- package/dist/configs/next.js +45 -18
- package/dist/constants/api-endpoints.d.ts +69 -0
- package/dist/constants/api-endpoints.js +34 -0
- package/dist/contracts/registry.d.ts +7 -0
- package/dist/features/admin/components/AdminEmployeeEditorView.d.ts +10 -0
- package/dist/features/admin/components/AdminEmployeeEditorView.js +168 -0
- package/dist/features/admin/components/AdminPrizeDrawsView.d.ts +4 -0
- package/dist/features/admin/components/AdminPrizeDrawsView.js +135 -0
- package/dist/features/admin/components/AdminSidebar.d.ts +2 -0
- package/dist/features/admin/components/AdminStoreEditorView.d.ts +2 -1
- package/dist/features/admin/components/AdminStoreEditorView.js +55 -3
- package/dist/features/admin/components/AdminStoresView.js +3 -1
- package/dist/features/admin/components/AdminSupportTicketDetailView.d.ts +23 -0
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +83 -0
- package/dist/features/admin/components/AdminSupportTicketsView.d.ts +4 -0
- package/dist/features/admin/components/AdminSupportTicketsView.js +151 -0
- package/dist/features/admin/components/AdminTeamView.d.ts +4 -0
- package/dist/features/admin/components/AdminTeamView.js +139 -0
- package/dist/features/admin/components/AdminUserEditorView.d.ts +14 -1
- package/dist/features/admin/components/AdminUserEditorView.js +116 -14
- package/dist/features/admin/components/AdminUsersView.js +39 -12
- package/dist/features/admin/components/index.d.ts +10 -0
- package/dist/features/admin/components/index.js +6 -0
- package/dist/features/admin/constants/filter-tabs.d.ts +71 -0
- package/dist/features/admin/constants/filter-tabs.js +33 -0
- package/dist/features/auth/server/checkSoftBan.d.ts +15 -0
- package/dist/features/auth/server/checkSoftBan.js +36 -0
- package/dist/features/auth/server.d.ts +1 -0
- package/dist/features/auth/server.js +1 -0
- package/dist/features/media/types/index.js +2 -1
- package/dist/features/seller/components/SellerPreOrdersView.d.ts +4 -0
- package/dist/features/seller/components/SellerPreOrdersView.js +141 -0
- package/dist/features/seller/components/SellerPrizeDrawsView.d.ts +4 -0
- package/dist/features/seller/components/SellerPrizeDrawsView.js +138 -0
- package/dist/features/seller/components/index.d.ts +4 -0
- package/dist/features/seller/components/index.js +2 -0
- package/dist/features/stores/repository/store.repository.d.ts +5 -1
- package/dist/features/stores/repository/store.repository.js +27 -2
- package/dist/features/support/repository/support.repository.d.ts +18 -0
- package/dist/features/support/repository/support.repository.js +117 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +21 -0
- package/dist/next/api/routeHandler.d.ts +8 -0
- package/dist/next/api/routeHandler.js +24 -3
- package/dist/next/routing/route-map.d.ts +2 -0
- package/dist/next/routing/route-map.js +1 -0
- package/dist/repositories/index.d.ts +2 -0
- package/dist/repositories/index.js +1 -0
- package/dist/security/pii-schemas.d.ts +2 -0
- package/dist/security/pii-schemas.js +2 -0
- package/dist/seed/stores-seed-data.js +8 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.js +6 -0
- package/dist/tailwind-utilities.css +1 -1
- package/dist/utils/media-url.d.ts +9 -0
- package/dist/utils/media-url.js +29 -0
- package/package.json +1 -1
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { firebaseFieldOps } from "../../../providers/db-firebase";
|
|
2
|
+
import { BaseRepository, prepareForFirestore, } from "../../../providers/db-firebase";
|
|
3
|
+
import { DatabaseError } from "../../../errors";
|
|
4
|
+
import { SUPPORT_TICKET_COLLECTION, ACTIVE_TICKET_STATUSES, } from "../schemas/firestore";
|
|
5
|
+
export class SupportRepository extends BaseRepository {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(SUPPORT_TICKET_COLLECTION);
|
|
8
|
+
}
|
|
9
|
+
async createTicket(input) {
|
|
10
|
+
try {
|
|
11
|
+
const now = new Date();
|
|
12
|
+
const data = {
|
|
13
|
+
...input,
|
|
14
|
+
status: "open",
|
|
15
|
+
priority: "normal",
|
|
16
|
+
messages: [],
|
|
17
|
+
createdAt: now,
|
|
18
|
+
updatedAt: now,
|
|
19
|
+
};
|
|
20
|
+
return this.create(data);
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
throw new DatabaseError("Failed to create support ticket", err);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async getUserTickets(userId, page = 1, pageSize = 20) {
|
|
27
|
+
const model = {
|
|
28
|
+
filters: `userId==${userId}`,
|
|
29
|
+
sorts: "-createdAt",
|
|
30
|
+
page,
|
|
31
|
+
pageSize,
|
|
32
|
+
};
|
|
33
|
+
return this.sieveQuery(model, SupportRepository.SIEVE_FIELDS, { defaultPageSize: pageSize, maxPageSize: 50 });
|
|
34
|
+
}
|
|
35
|
+
async getTicketById(ticketId) {
|
|
36
|
+
return this.findById(ticketId);
|
|
37
|
+
}
|
|
38
|
+
async countActiveTickets(userId) {
|
|
39
|
+
const col = this.db.collection(SUPPORT_TICKET_COLLECTION);
|
|
40
|
+
const snaps = await Promise.all(ACTIVE_TICKET_STATUSES.map((s) => col
|
|
41
|
+
.where("userId", "==", userId)
|
|
42
|
+
.where("status", "==", s)
|
|
43
|
+
.select()
|
|
44
|
+
.get()));
|
|
45
|
+
return snaps.reduce((total, snap) => total + snap.size, 0);
|
|
46
|
+
}
|
|
47
|
+
async getActiveOrderTicket(userId, orderId) {
|
|
48
|
+
const col = this.db.collection(SUPPORT_TICKET_COLLECTION);
|
|
49
|
+
const snap = await col
|
|
50
|
+
.where("userId", "==", userId)
|
|
51
|
+
.where("orderId", "==", orderId)
|
|
52
|
+
.where("status", "in", ACTIVE_TICKET_STATUSES)
|
|
53
|
+
.limit(1)
|
|
54
|
+
.get();
|
|
55
|
+
if (snap.empty)
|
|
56
|
+
return null;
|
|
57
|
+
const doc = snap.docs[0];
|
|
58
|
+
return { id: doc.id, ...doc.data() };
|
|
59
|
+
}
|
|
60
|
+
async getActiveCategoryTicket(userId, category) {
|
|
61
|
+
const col = this.db.collection(SUPPORT_TICKET_COLLECTION);
|
|
62
|
+
const snap = await col
|
|
63
|
+
.where("userId", "==", userId)
|
|
64
|
+
.where("category", "==", category)
|
|
65
|
+
.where("status", "==", "waiting_on_user")
|
|
66
|
+
.limit(1)
|
|
67
|
+
.get();
|
|
68
|
+
if (snap.empty)
|
|
69
|
+
return null;
|
|
70
|
+
const doc = snap.docs[0];
|
|
71
|
+
return { id: doc.id, ...doc.data() };
|
|
72
|
+
}
|
|
73
|
+
async updateTicketStatus(ticketId, update) {
|
|
74
|
+
return this.update(ticketId, {
|
|
75
|
+
...update,
|
|
76
|
+
updatedAt: new Date(),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
async addMessage(ticketId, message, newStatus) {
|
|
80
|
+
try {
|
|
81
|
+
const ref = this.db
|
|
82
|
+
.collection(SUPPORT_TICKET_COLLECTION)
|
|
83
|
+
.doc(ticketId);
|
|
84
|
+
const updateData = {
|
|
85
|
+
messages: firebaseFieldOps.arrayUnion(prepareForFirestore(message)),
|
|
86
|
+
updatedAt: new Date(),
|
|
87
|
+
};
|
|
88
|
+
if (newStatus)
|
|
89
|
+
updateData.status = newStatus;
|
|
90
|
+
await ref.update(updateData);
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
throw new DatabaseError("Failed to add message to ticket", err);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async assignTicket(ticketId, assignedTo, assignedToName) {
|
|
97
|
+
return this.update(ticketId, {
|
|
98
|
+
assignedTo,
|
|
99
|
+
assignedToName,
|
|
100
|
+
updatedAt: new Date(),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
async listAll(model) {
|
|
104
|
+
return this.sieveQuery(model, SupportRepository.SIEVE_FIELDS, { defaultPageSize: 25, maxPageSize: 100 });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
SupportRepository.SIEVE_FIELDS = {
|
|
108
|
+
userId: { canFilter: true, canSort: false },
|
|
109
|
+
status: { canFilter: true, canSort: false },
|
|
110
|
+
category: { canFilter: true, canSort: false },
|
|
111
|
+
priority: { canFilter: true, canSort: false },
|
|
112
|
+
assignedTo: { canFilter: true, canSort: false },
|
|
113
|
+
orderId: { canFilter: true, canSort: false },
|
|
114
|
+
createdAt: { canFilter: true, canSort: true },
|
|
115
|
+
updatedAt: { canFilter: true, canSort: true },
|
|
116
|
+
};
|
|
117
|
+
export const supportRepository = new SupportRepository();
|
package/dist/index.d.ts
CHANGED
|
@@ -526,6 +526,9 @@ export { siteSettingsRepository } from "./repositories/index";
|
|
|
526
526
|
export { smsCounterRepository } from "./repositories/index";
|
|
527
527
|
export { storeRepository } from "./repositories/index";
|
|
528
528
|
export { scammerRepository } from "./repositories/index";
|
|
529
|
+
export { supportRepository, SupportRepository } from "./repositories/index";
|
|
530
|
+
export type { SupportTicketDocument, SupportTicketCreateInput, SupportTicketUpdateInput, TicketMessage, TicketCategory, TicketStatus, TicketPriority, } from "./repositories/index";
|
|
531
|
+
export { ELIGIBLE_ORDER_STATUSES_FOR_TICKET } from "./features/support/schemas/firestore";
|
|
529
532
|
export { productFeaturesRepository } from "./repositories/index";
|
|
530
533
|
export type { ProductFeatureListFilter } from "./repositories/index";
|
|
531
534
|
export { loadProductFeaturesForStore } from "./repositories/index";
|
|
@@ -1082,6 +1085,8 @@ export { QuickEditMenu } from "./features/admin/index";
|
|
|
1082
1085
|
export type { QuickEditAction, QuickEditMenuProps } from "./features/admin/index";
|
|
1083
1086
|
export { AdminPageHeader } from "./features/admin/index";
|
|
1084
1087
|
export { AdminPayoutsView } from "./features/admin/index";
|
|
1088
|
+
export { AdminPrizeDrawsView } from "./features/admin/index";
|
|
1089
|
+
export type { AdminPrizeDrawsViewProps } from "./features/admin/index";
|
|
1085
1090
|
export { AdminProductsView } from "./features/admin/index";
|
|
1086
1091
|
export { AdminProductEditorView } from "./features/admin/index";
|
|
1087
1092
|
export type { AdminProductEditorViewProps } from "./features/admin/index";
|
|
@@ -1132,6 +1137,10 @@ export { DEFAULT_SITE_SETTINGS_DATA } from "./features/admin/index";
|
|
|
1132
1137
|
export { DEFAULT_TRUST_BAR_ITEMS } from "./features/admin/index";
|
|
1133
1138
|
export { DashboardStatsGrid } from "./features/admin/index";
|
|
1134
1139
|
export { DemoSeedView } from "./features/admin/index";
|
|
1140
|
+
export { AdminTeamView } from "./features/admin/index";
|
|
1141
|
+
export { AdminEmployeeEditorView } from "./features/admin/index";
|
|
1142
|
+
export { AdminSupportTicketsView } from "./features/admin/index";
|
|
1143
|
+
export { AdminSupportTicketDetailView } from "./features/admin/index";
|
|
1135
1144
|
export { DrawerFormFooter } from "./features/admin/index";
|
|
1136
1145
|
export { FEATURE_FLAG_META } from "./features/admin/index";
|
|
1137
1146
|
export { NOTIFICATIONS_COLLECTION } from "./features/admin/index";
|
|
@@ -1206,6 +1215,10 @@ export type { ChatRoomDocument } from "./features/admin/index";
|
|
|
1206
1215
|
export type { ChatRoomUpdateInput } from "./features/admin/index";
|
|
1207
1216
|
export type { DashboardStats } from "./features/admin/index";
|
|
1208
1217
|
export type { DemoSeedViewProps } from "./features/admin/index";
|
|
1218
|
+
export type { AdminTeamViewProps } from "./features/admin/index";
|
|
1219
|
+
export type { AdminEmployeeEditorViewProps } from "./features/admin/index";
|
|
1220
|
+
export type { AdminSupportTicketsViewProps } from "./features/admin/index";
|
|
1221
|
+
export type { AdminSupportTicketDetailViewProps } from "./features/admin/index";
|
|
1209
1222
|
export type { DrawerFormFooterProps } from "./features/admin/index";
|
|
1210
1223
|
export type { FeatureFlagKey } from "./features/admin/index";
|
|
1211
1224
|
export type { FeatureFlagMeta } from "./features/admin/index";
|
|
@@ -2605,6 +2618,10 @@ export { SellerPayoutHistoryTable } from "./features/seller/index";
|
|
|
2605
2618
|
export { SellerPayoutSettingsView } from "./features/seller/index";
|
|
2606
2619
|
export { SellerPayoutStats } from "./features/seller/index";
|
|
2607
2620
|
export { SellerPayoutsView } from "./features/seller/index";
|
|
2621
|
+
export { SellerPreOrdersView } from "./features/seller/index";
|
|
2622
|
+
export type { SellerPreOrdersViewProps } from "./features/seller/index";
|
|
2623
|
+
export { SellerPrizeDrawsView } from "./features/seller/index";
|
|
2624
|
+
export type { SellerPrizeDrawsViewProps } from "./features/seller/index";
|
|
2608
2625
|
export { SellerProductsView } from "./features/seller/index";
|
|
2609
2626
|
export { SellerRevenueChart } from "./features/seller/index";
|
|
2610
2627
|
export { SellerShippingView } from "./features/seller/index";
|
|
@@ -2967,6 +2984,7 @@ export { formatFileSize } from "./utils/number.formatter";
|
|
|
2967
2984
|
export { formatMonthYear } from "./utils/date.formatter";
|
|
2968
2985
|
export { generateMediaFilename } from "./utils/id-generators";
|
|
2969
2986
|
export type { MediaFilenameContext } from "./utils/id-generators";
|
|
2987
|
+
export { resolveMediaUrl } from "./utils/media-url";
|
|
2970
2988
|
export { generateFAQId } from "./utils/id-generators";
|
|
2971
2989
|
export type { GenerateFAQIdInput } from "./utils/id-generators";
|
|
2972
2990
|
export { generateCroppedImageFilename } from "./utils/id-generators";
|
package/dist/index.js
CHANGED
|
@@ -1082,6 +1082,9 @@ export { storeRepository } from "./repositories/index";
|
|
|
1082
1082
|
// [DB]-Database layer — uses firebase-admin or another server-side DB SDK; can only run in a trusted server environment.
|
|
1083
1083
|
// scammerRepository - Shared export for scammer profiles repository.
|
|
1084
1084
|
export { scammerRepository } from "./repositories/index";
|
|
1085
|
+
// supportRepository - Server-only repository for support tickets (BAN1).
|
|
1086
|
+
export { supportRepository, SupportRepository } from "./repositories/index";
|
|
1087
|
+
export { ELIGIBLE_ORDER_STATUSES_FOR_TICKET } from "./features/support/schemas/firestore";
|
|
1085
1088
|
// SB-UNI-B — sublistingCategoriesRepository + SublistingCategoryDocument deleted.
|
|
1086
1089
|
// Use categoriesRepository.findBySlugAndType(slug, "sublisting") and CategoryDocument with categoryType:"sublisting".
|
|
1087
1090
|
// [DB]-Database layer — uses firebase-admin; server-only.
|
|
@@ -2129,6 +2132,9 @@ export { AdminPageHeader } from "./features/admin/index";
|
|
|
2129
2132
|
// AdminPayoutsView - Component for admin payouts view.
|
|
2130
2133
|
export { AdminPayoutsView } from "./features/admin/index";
|
|
2131
2134
|
// [CLIENT-SSR]-Runs in both SSR and browser — React component or hook that does not depend on browser-only APIs.
|
|
2135
|
+
// AdminPrizeDrawsView - Component for admin prize draws listing view (SB4-E).
|
|
2136
|
+
export { AdminPrizeDrawsView } from "./features/admin/index";
|
|
2137
|
+
// [CLIENT-SSR]-Runs in both SSR and browser — React component or hook that does not depend on browser-only APIs.
|
|
2132
2138
|
// AdminProductsView - Component for admin products view.
|
|
2133
2139
|
export { AdminProductsView } from "./features/admin/index";
|
|
2134
2140
|
// AdminProductEditorView - Component for admin product create/edit form (3-mode: standard/auction/pre-order).
|
|
@@ -2231,6 +2237,14 @@ export { DashboardStatsGrid } from "./features/admin/index";
|
|
|
2231
2237
|
// [CLIENT-SSR]-Runs in both SSR and browser — React component or hook that does not depend on browser-only APIs.
|
|
2232
2238
|
// DemoSeedView - Component for demo seed view.
|
|
2233
2239
|
export { DemoSeedView } from "./features/admin/index";
|
|
2240
|
+
// AdminTeamView - Employee management list view.
|
|
2241
|
+
export { AdminTeamView } from "./features/admin/index";
|
|
2242
|
+
// AdminEmployeeEditorView - Invite/edit employee permissions SideDrawer.
|
|
2243
|
+
export { AdminEmployeeEditorView } from "./features/admin/index";
|
|
2244
|
+
// AdminSupportTicketsView - Admin support ticket list view.
|
|
2245
|
+
export { AdminSupportTicketsView } from "./features/admin/index";
|
|
2246
|
+
// AdminSupportTicketDetailView - Admin support ticket detail/reply SideDrawer.
|
|
2247
|
+
export { AdminSupportTicketDetailView } from "./features/admin/index";
|
|
2234
2248
|
// [CLIENT-SSR]-Runs in both SSR and browser — React component or hook that does not depend on browser-only APIs.
|
|
2235
2249
|
// DrawerFormFooter - Shared export for drawer form footer.
|
|
2236
2250
|
export { DrawerFormFooter } from "./features/admin/index";
|
|
@@ -4877,6 +4891,12 @@ export { SellerPayoutStats } from "./features/seller/index";
|
|
|
4877
4891
|
// SellerPayoutsView - Component for seller payouts view.
|
|
4878
4892
|
export { SellerPayoutsView } from "./features/seller/index";
|
|
4879
4893
|
// [CLIENT-SSR]-Runs in both SSR and browser — React component or hook that does not depend on browser-only APIs.
|
|
4894
|
+
// SellerPreOrdersView - Component for seller pre-orders listing view (SB4-E).
|
|
4895
|
+
export { SellerPreOrdersView } from "./features/seller/index";
|
|
4896
|
+
// [CLIENT-SSR]-Runs in both SSR and browser — React component or hook that does not depend on browser-only APIs.
|
|
4897
|
+
// SellerPrizeDrawsView - Component for seller prize draws listing view (SB4-E).
|
|
4898
|
+
export { SellerPrizeDrawsView } from "./features/seller/index";
|
|
4899
|
+
// [CLIENT-SSR]-Runs in both SSR and browser — React component or hook that does not depend on browser-only APIs.
|
|
4880
4900
|
// SellerProductsView - Component for seller products view.
|
|
4881
4901
|
export { SellerProductsView } from "./features/seller/index";
|
|
4882
4902
|
// [CLIENT-SSR]-Runs in both SSR and browser — React component or hook that does not depend on browser-only APIs.
|
|
@@ -5424,6 +5444,7 @@ export { buildSieveFilters } from "./utils/filter.helper";
|
|
|
5424
5444
|
export { formatFileSize } from "./utils/number.formatter";
|
|
5425
5445
|
export { formatMonthYear } from "./utils/date.formatter";
|
|
5426
5446
|
export { generateMediaFilename } from "./utils/id-generators"; // generateProductImageFilename already exported from "./utils/id-generators";
|
|
5447
|
+
export { resolveMediaUrl } from "./utils/media-url";
|
|
5427
5448
|
export { generateFAQId } from "./utils/id-generators";
|
|
5428
5449
|
export { generateCroppedImageFilename } from "./utils/id-generators";
|
|
5429
5450
|
// Messages / Conversations feature schemas
|
|
@@ -48,6 +48,14 @@ interface RouteHandlerOptions<TInput = unknown, TParams = Record<string, string>
|
|
|
48
48
|
* Implies `auth: true`.
|
|
49
49
|
*/
|
|
50
50
|
roles?: string[];
|
|
51
|
+
/**
|
|
52
|
+
* Fine-grained permission required for this route.
|
|
53
|
+
* When set: also allows `"employee"` role through the role check, then
|
|
54
|
+
* verifies the permission via the registered `rbac` provider.
|
|
55
|
+
* Admin role always bypasses. Requires `rbac` provider to be registered.
|
|
56
|
+
* Implies `auth: true`.
|
|
57
|
+
*/
|
|
58
|
+
permission?: string;
|
|
51
59
|
/** Zod schema to validate + parse the JSON request body. */
|
|
52
60
|
schema?: ParseableSchema<TInput>;
|
|
53
61
|
/**
|
|
@@ -68,7 +68,9 @@ export function createRouteHandler(options) {
|
|
|
68
68
|
try {
|
|
69
69
|
// -- Auth --------------------------------------------------------------
|
|
70
70
|
let user;
|
|
71
|
-
const needsAuth = options.auth ||
|
|
71
|
+
const needsAuth = options.auth ||
|
|
72
|
+
(options.roles && options.roles.length > 0) ||
|
|
73
|
+
!!options.permission;
|
|
72
74
|
if (needsAuth) {
|
|
73
75
|
user = await verifySession(request);
|
|
74
76
|
}
|
|
@@ -80,8 +82,27 @@ export function createRouteHandler(options) {
|
|
|
80
82
|
// No valid session — continue as anonymous
|
|
81
83
|
}
|
|
82
84
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
+
// Role check — when `permission` is set, also allow "employee" through
|
|
86
|
+
const effectiveRoles = options.roles
|
|
87
|
+
? options.permission
|
|
88
|
+
? [...new Set([...options.roles, "employee"])]
|
|
89
|
+
: options.roles
|
|
90
|
+
: options.permission
|
|
91
|
+
? ["admin", "employee"]
|
|
92
|
+
: [];
|
|
93
|
+
if (effectiveRoles.length > 0) {
|
|
94
|
+
if (!user || !effectiveRoles.includes(user.role ?? "")) {
|
|
95
|
+
return NextResponse.json({ success: false, error: "Insufficient permissions" }, { status: 403 });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// -- Permission check (employee fine-grained) --------------------------
|
|
99
|
+
if (options.permission && user && user.role !== "admin") {
|
|
100
|
+
const { rbac } = getProviders();
|
|
101
|
+
if (!rbac) {
|
|
102
|
+
return NextResponse.json({ success: false, error: "RBAC provider not configured" }, { status: 503 });
|
|
103
|
+
}
|
|
104
|
+
const perms = await rbac.getPermissions(user.uid);
|
|
105
|
+
if (!perms.includes(options.permission)) {
|
|
85
106
|
return NextResponse.json({ success: false, error: "Insufficient permissions" }, { status: 403 });
|
|
86
107
|
}
|
|
87
108
|
}
|
|
@@ -230,6 +230,7 @@ export declare const DEFAULT_ROUTE_MAP: {
|
|
|
230
230
|
readonly BUNDLES_EDIT: (id: string) => string;
|
|
231
231
|
readonly PRIZE_DRAWS: "/admin/prize-draws";
|
|
232
232
|
readonly PRIZE_DRAWS_EDIT: (id: string) => string;
|
|
233
|
+
readonly TEAM: "/admin/team";
|
|
233
234
|
};
|
|
234
235
|
readonly DEMO: {
|
|
235
236
|
readonly SEED: "/demo/seed";
|
|
@@ -459,6 +460,7 @@ export declare const ROUTES: {
|
|
|
459
460
|
readonly BUNDLES_EDIT: (id: string) => string;
|
|
460
461
|
readonly PRIZE_DRAWS: "/admin/prize-draws";
|
|
461
462
|
readonly PRIZE_DRAWS_EDIT: (id: string) => string;
|
|
463
|
+
readonly TEAM: "/admin/team";
|
|
462
464
|
};
|
|
463
465
|
readonly DEMO: {
|
|
464
466
|
readonly SEED: "/demo/seed";
|
|
@@ -221,6 +221,7 @@ export const DEFAULT_ROUTE_MAP = {
|
|
|
221
221
|
BUNDLES_EDIT: (id) => `/admin/bundles/${id}/edit`,
|
|
222
222
|
PRIZE_DRAWS: "/admin/prize-draws",
|
|
223
223
|
PRIZE_DRAWS_EDIT: (id) => `/admin/prize-draws/${id}/edit`,
|
|
224
|
+
TEAM: "/admin/team",
|
|
224
225
|
},
|
|
225
226
|
DEMO: {
|
|
226
227
|
SEED: "/demo/seed",
|
|
@@ -37,6 +37,8 @@ export type { NewsletterSubscriberDocument, NewsletterSubscriberCreateInput, New
|
|
|
37
37
|
export { CopilotLogRepository, copilotLogRepository } from "../core";
|
|
38
38
|
export type { CopilotFeedback, CopilotLogDocument, CopilotLogCreateInput, } from "../core";
|
|
39
39
|
export { ScammerRepository, scammerRepository, } from "../features/scams/repository/scammer.repository";
|
|
40
|
+
export { SupportRepository, supportRepository, } from "../features/support/repository/support.repository";
|
|
41
|
+
export type { SupportTicketDocument, SupportTicketCreateInput, SupportTicketUpdateInput, TicketMessage, TicketCategory, TicketStatus, TicketPriority, } from "../features/support/schemas/firestore";
|
|
40
42
|
export { ProductTemplateRepository, productTemplateRepository, } from "../features/products/repository/product-templates.repository";
|
|
41
43
|
export type { ProductTemplateDocument, ProductTemplateCreateInput, ProductTemplateUpdateInput, } from "../features/products/schemas/product-templates";
|
|
42
44
|
export { ProductFeaturesRepository, productFeaturesRepository, } from "../features/products/repository/product-features.repository";
|
|
@@ -43,6 +43,7 @@ export { EventEntryRepository, EventEntriesRepository, eventEntryRepository, } f
|
|
|
43
43
|
export { NewsletterRepository, newsletterRepository, } from "../core/newsletter.repository";
|
|
44
44
|
export { CopilotLogRepository, copilotLogRepository } from "../core";
|
|
45
45
|
export { ScammerRepository, scammerRepository, } from "../features/scams/repository/scammer.repository";
|
|
46
|
+
export { SupportRepository, supportRepository, } from "../features/support/repository/support.repository";
|
|
46
47
|
// SB-UNI-B — SublistingCategoriesRepository deleted; sublistings now live on
|
|
47
48
|
// categoriesRepository with categoryType:"sublisting".
|
|
48
49
|
export { ProductTemplateRepository, productTemplateRepository, } from "../features/products/repository/product-templates.repository";
|
|
@@ -36,3 +36,5 @@ export declare const OFFER_PII_FIELDS: readonly ["buyerName", "buyerEmail", "sel
|
|
|
36
36
|
export declare const CHAT_PII_FIELDS: readonly ["buyerName", "sellerName"];
|
|
37
37
|
/** PII fields in event entries */
|
|
38
38
|
export declare const EVENT_ENTRY_PII_FIELDS: readonly ["userDisplayName", "userEmail", "ipAddress"];
|
|
39
|
+
/** Store OAuth bearer tokens — encrypted via SETTINGS_ENCRYPTION_KEY */
|
|
40
|
+
export declare const STORE_SECRET_FIELDS: readonly ["whatsappConfig.accessToken"];
|
|
@@ -59,6 +59,7 @@ export const storesSeedData = [
|
|
|
59
59
|
totalReviews: 0,
|
|
60
60
|
averageRating: 0,
|
|
61
61
|
},
|
|
62
|
+
capabilities: ["host_auctions", "host_preorders", "suggest_brands", "create_coupons", "bulk_listing_import", "verified_seller", "featured_placement", "promotional_banner", "advanced_analytics", "api_access", "multiple_stores", "early_access_features", "whatsapp_catalog_sync"],
|
|
62
63
|
createdAt: daysAgo(400),
|
|
63
64
|
updatedAt: daysAgo(1),
|
|
64
65
|
},
|
|
@@ -119,6 +120,7 @@ export const storesSeedData = [
|
|
|
119
120
|
totalReviews: 42,
|
|
120
121
|
averageRating: 4.8,
|
|
121
122
|
},
|
|
123
|
+
capabilities: ["host_auctions", "host_preorders", "suggest_brands", "create_coupons", "verified_seller", "featured_placement", "extended_return_window"],
|
|
122
124
|
createdAt: daysAgo(380),
|
|
123
125
|
updatedAt: daysAgo(2),
|
|
124
126
|
},
|
|
@@ -148,6 +150,7 @@ export const storesSeedData = [
|
|
|
148
150
|
totalReviews: 31,
|
|
149
151
|
averageRating: 4.6,
|
|
150
152
|
},
|
|
153
|
+
capabilities: ["suggest_brands", "create_coupons", "verified_seller", "extended_return_window"],
|
|
151
154
|
createdAt: daysAgo(350),
|
|
152
155
|
updatedAt: daysAgo(3),
|
|
153
156
|
},
|
|
@@ -178,6 +181,7 @@ export const storesSeedData = [
|
|
|
178
181
|
totalReviews: 58,
|
|
179
182
|
averageRating: 4.9,
|
|
180
183
|
},
|
|
184
|
+
capabilities: ["suggest_brands", "create_coupons"],
|
|
181
185
|
createdAt: daysAgo(320),
|
|
182
186
|
updatedAt: daysAgo(1),
|
|
183
187
|
},
|
|
@@ -207,6 +211,7 @@ export const storesSeedData = [
|
|
|
207
211
|
totalReviews: 47,
|
|
208
212
|
averageRating: 4.7,
|
|
209
213
|
},
|
|
214
|
+
capabilities: ["host_auctions", "suggest_brands", "create_coupons", "extended_return_window"],
|
|
210
215
|
createdAt: daysAgo(290),
|
|
211
216
|
updatedAt: daysAgo(2),
|
|
212
217
|
},
|
|
@@ -237,6 +242,7 @@ export const storesSeedData = [
|
|
|
237
242
|
totalReviews: 28,
|
|
238
243
|
averageRating: 4.8,
|
|
239
244
|
},
|
|
245
|
+
capabilities: ["suggest_brands", "create_coupons", "whatsapp_catalog_sync"],
|
|
240
246
|
createdAt: daysAgo(260),
|
|
241
247
|
updatedAt: daysAgo(1),
|
|
242
248
|
},
|
|
@@ -267,6 +273,7 @@ export const storesSeedData = [
|
|
|
267
273
|
totalReviews: 22,
|
|
268
274
|
averageRating: 4.7,
|
|
269
275
|
},
|
|
276
|
+
capabilities: ["host_preorders", "suggest_brands", "create_coupons", "extended_return_window"],
|
|
270
277
|
createdAt: daysAgo(230),
|
|
271
278
|
updatedAt: daysAgo(2),
|
|
272
279
|
},
|
|
@@ -296,6 +303,7 @@ export const storesSeedData = [
|
|
|
296
303
|
totalReviews: 19,
|
|
297
304
|
averageRating: 4.9,
|
|
298
305
|
},
|
|
306
|
+
capabilities: ["suggest_brands", "create_coupons", "featured_placement"],
|
|
299
307
|
createdAt: daysAgo(200),
|
|
300
308
|
updatedAt: daysAgo(3),
|
|
301
309
|
},
|
package/dist/server.d.ts
CHANGED
|
@@ -477,3 +477,9 @@ export { applyMediaContextGuards, CONTEXT_LIMITS, } from "./_internal/server/fea
|
|
|
477
477
|
export type { GuardResult, GuardError, GuardSuccess } from "./_internal/server/features/media/contextGuards";
|
|
478
478
|
export { MEGABYTE, MAX_IMAGE_BYTES, MAX_PDF_BYTES, MAX_VIDEO_BYTES, MAX_LABEL, MAX_BYTES, ALLOWED_IMAGE_MIMES, ALLOWED_VIDEO_MIMES, ALLOWED_DOC_MIMES, ALLOWED_MIMES, ALLOWED_TYPES_LABEL, MIME_TO_EXT, PDF_MAGIC, VIDEO_CONVERSION_HINTS, classifyMime, isAllowedMime, maxBytesFor, getConversionHint, } from "./_internal/shared/media/limits";
|
|
479
479
|
export type { MediaKind, AllowedImageMime, AllowedVideoMime, AllowedDocMime, AllowedMime, } from "./_internal/shared/media/limits";
|
|
480
|
+
export { getServerPermissions, checkPermission, checkAnyPermission, makeAdminSectionLayout, } from "./_internal/server/features/auth/permissions";
|
|
481
|
+
export type { ResolvedPermissions, AdminSectionLayoutOpts, } from "./_internal/server/features/auth/permissions";
|
|
482
|
+
export { getStoreCapabilities, storeHasCapability, } from "./_internal/server/features/auth/capabilities";
|
|
483
|
+
export { isSoftBanned, getBanSummary } from "./features/auth/server/checkSoftBan";
|
|
484
|
+
export type { UserSoftBan } from "./features/auth/schemas/firestore";
|
|
485
|
+
export type { BannedAction } from "./features/auth/permissions/constants";
|
package/dist/server.js
CHANGED
|
@@ -1350,3 +1350,9 @@ export { LISTING_TYPE_REGISTRY, pluginFor } from "./_internal/shared/listing-typ
|
|
|
1350
1350
|
export { applyMediaContextGuards, CONTEXT_LIMITS, } from "./_internal/server/features/media/contextGuards";
|
|
1351
1351
|
// Media upload limits — shared by /api/media/sign + /api/media/finalize + /api/media/upload.
|
|
1352
1352
|
export { MEGABYTE, MAX_IMAGE_BYTES, MAX_PDF_BYTES, MAX_VIDEO_BYTES, MAX_LABEL, MAX_BYTES, ALLOWED_IMAGE_MIMES, ALLOWED_VIDEO_MIMES, ALLOWED_DOC_MIMES, ALLOWED_MIMES, ALLOWED_TYPES_LABEL, MIME_TO_EXT, PDF_MAGIC, VIDEO_CONVERSION_HINTS, classifyMime, isAllowedMime, maxBytesFor, getConversionHint, } from "./_internal/shared/media/limits";
|
|
1353
|
+
// ── RBAC server helpers ───────────────────────────────────────────────────────
|
|
1354
|
+
// getServerPermissions, checkPermission, makeAdminSectionLayout
|
|
1355
|
+
export { getServerPermissions, checkPermission, checkAnyPermission, makeAdminSectionLayout, } from "./_internal/server/features/auth/permissions";
|
|
1356
|
+
export { getStoreCapabilities, storeHasCapability, } from "./_internal/server/features/auth/capabilities";
|
|
1357
|
+
// ── Soft ban helpers ──────────────────────────────────────────────────────────
|
|
1358
|
+
export { isSoftBanned, getBanSummary } from "./features/auth/server/checkSoftBan";
|