@infuro/cms-core 1.0.34 → 1.0.35
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/README.md +13 -0
- package/dist/OrderTrackPage-W3J6WIG2.js +426 -0
- package/dist/OrderTrackPage-Z6FCJQYY.cjs +428 -0
- package/dist/admin.cjs +34329 -20923
- package/dist/admin.d.cts +186 -9
- package/dist/admin.d.ts +186 -9
- package/dist/admin.js +34140 -20829
- package/dist/api.cjs +120 -17515
- package/dist/api.d.cts +633 -3
- package/dist/api.d.ts +633 -3
- package/dist/api.js +14 -17528
- package/dist/auth.cjs +192 -1034
- package/dist/auth.d.cts +194 -51
- package/dist/auth.d.ts +194 -51
- package/dist/auth.js +4 -966
- package/dist/chunk-2XE4X74C.js +29602 -0
- package/dist/chunk-3DZRIZOD.cjs +52 -0
- package/dist/chunk-3KPNTQBV.cjs +620 -0
- package/dist/chunk-46GKADYE.cjs +84 -0
- package/dist/chunk-4TRPKBKO.js +589 -0
- package/dist/chunk-5ELSW2UP.js +150 -0
- package/dist/chunk-6KPQWRFW.js +171 -0
- package/dist/chunk-7NMT3GBR.cjs +29 -0
- package/dist/chunk-7YIBMQDR.cjs +86 -0
- package/dist/chunk-BGJAV67S.cjs +29710 -0
- package/dist/chunk-CNTSLED2.cjs +559 -0
- package/dist/chunk-CRFV5WJK.js +16 -0
- package/dist/chunk-D5FBNKQM.cjs +104 -0
- package/dist/chunk-EF2JBPDM.js +114 -0
- package/dist/chunk-EQPITOP6.js +543 -0
- package/dist/chunk-GO7PPYNU.js +76 -0
- package/dist/chunk-HF3L2GIT.cjs +194 -0
- package/dist/chunk-J7XHLOLO.js +830 -0
- package/dist/chunk-JBRR5UYL.js +87 -0
- package/dist/chunk-JC6DLWTE.js +21 -0
- package/dist/chunk-JHF4YYRC.cjs +188 -0
- package/dist/chunk-JXF23MPG.js +25 -0
- package/dist/chunk-MQBT33IV.js +48 -0
- package/dist/chunk-N44BJZ4C.cjs +123 -0
- package/dist/chunk-OOTLNH63.cjs +18 -0
- package/dist/chunk-PAMVINEX.cjs +577 -0
- package/dist/chunk-PNOKNSG2.cjs +222 -0
- package/dist/chunk-QM733NUK.js +186 -0
- package/dist/chunk-R73BKDRO.cjs +90 -0
- package/dist/chunk-SHUYVCID.js +4 -0
- package/dist/chunk-SYBOCAWB.js +97 -0
- package/dist/chunk-TDV6EJHV.js +192 -0
- package/dist/chunk-TFUOHI37.cjs +839 -0
- package/dist/chunk-TIAEXJLI.cjs +182 -0
- package/dist/chunk-UPLVMVRX.cjs +23 -0
- package/dist/chunk-USNT2KNT.cjs +6 -0
- package/dist/chunk-WEMDMVHQ.js +216 -0
- package/dist/chunk-XDSNZUW7.js +564 -0
- package/dist/chunk-XQ3QUHWR.cjs +83 -0
- package/dist/chunk-XW5ATPRW.cjs +155 -0
- package/dist/chunk-ZQ4X6OAU.js +82 -0
- package/dist/chunk-ZSVCP6N3.js +83 -0
- package/dist/cli.cjs +103 -84
- package/dist/cli.js +62 -27
- package/dist/email-FKR4FXFI.js +5 -0
- package/dist/email-KVKVPNCL.cjs +58 -0
- package/dist/email-queue-CGZBVVAS.js +2 -0
- package/dist/email-queue-TPZWLTIV.cjs +23 -0
- package/dist/erp-config-enabled-CUMQ6N2V.cjs +11 -0
- package/dist/erp-config-enabled-T37X7T34.js +2 -0
- package/dist/erp-order-invoice-3YISSOWW.js +3 -0
- package/dist/erp-order-invoice-ZR5F2KTA.cjs +12 -0
- package/dist/event-order-defaults-6E543227.js +2 -0
- package/dist/event-order-defaults-DUGDVGJI.cjs +39 -0
- package/dist/event-order-notifications-5GSAOYVS.cjs +27 -0
- package/dist/event-order-notifications-IIIF23D5.js +10 -0
- package/dist/hooks.cjs +259 -132
- package/dist/hooks.d.cts +42 -1
- package/dist/hooks.d.ts +42 -1
- package/dist/hooks.js +234 -91
- package/dist/index.cjs +3884 -22307
- package/dist/index.d.cts +2203 -772
- package/dist/index.d.ts +2203 -772
- package/dist/index.js +2871 -22064
- package/dist/interpolate-WAKPN56R.cjs +11 -0
- package/dist/interpolate-WDUWDF3I.js +2 -0
- package/dist/layout-36UFTHC5.cjs +11 -0
- package/dist/layout-AOBN26XG.js +2 -0
- package/dist/migrations/1779400000000-ConvertStatusToEnum.ts +142 -0
- package/dist/migrations/1779400000000-SeedDefaultCurrencies.ts +33 -0
- package/dist/migrations/1779500000000-VendorRolesAndPermissions.ts +102 -0
- package/dist/migrations/1779600000000-VendorRegistrationProfile.ts +52 -0
- package/dist/migrations/1779700000000-CollectionIsCatalog.ts +22 -0
- package/dist/migrations/1779710000000-CollectionPlatformCatalog.ts +60 -0
- package/dist/migrations/1779720000000-ProductCategoryPlatformCatalog.ts +157 -0
- package/dist/migrations/1779800000000-EventsAndEventProducts.ts +173 -0
- package/dist/migrations/1779810000000-BackfillVendorRoleEventsPermissions.ts +38 -0
- package/dist/migrations/1779820000000-FixProductsCategoryForeignKey.ts +70 -0
- package/dist/migrations/1779830000000-ProductTitleColumn.ts +32 -0
- package/dist/migrations/1779840000000-EventAboutAndVisibilityFields.ts +34 -0
- package/dist/migrations/1779850000000-EventCityCountrySplit.ts +43 -0
- package/dist/migrations/1779860000000-CreateCombos.ts +140 -0
- package/dist/migrations/1780100000000-OrderAttendeesEventId.ts +55 -0
- package/dist/migrations/1780110000000-EventContactFormId.ts +49 -0
- package/dist/migrations/1780130000000-ProductVariants.ts +54 -0
- package/dist/migrations/1780140000000-EventManagementEnhancements.ts +44 -0
- package/dist/migrations/1780160000000-EventRegistrationGstProductContactForm.ts +79 -0
- package/dist/migrations/1780170000000-ComboCurrencyPrices.ts +20 -0
- package/dist/migrations/1781110000000-VendorOwnerCombosPermission.ts +38 -0
- package/dist/migrations/1781120000000-RefundPoliciesAndRequests.ts +225 -0
- package/dist/migrations/1781130000000-CreateAttendees.ts +44 -0
- package/dist/migrations/1781140000000-EventOrderNotifications.ts +29 -0
- package/dist/migrations/1781150000000-EventNamedLists.ts +28 -0
- package/dist/migrations/1781160000000-RefundPolicyEventTiers.ts +27 -0
- package/dist/migrations/1781170000000-EventRefundPolicy.ts +42 -0
- package/dist/migrations/1781180000000-RemoveCartItemsUniqueConstraint.ts +15 -0
- package/dist/migrations/1781190000000-RenameProductTaxesToProductConfig.ts +84 -0
- package/dist/migrations/1781200000000-VendorOwnerProductConfigPermissions.ts +51 -0
- package/dist/migrations/1781210000000-VendorRoleProductConfigPermissions.ts +46 -0
- package/dist/migrations/helpers/vendor-role-seed.ts +243 -0
- package/dist/paid-order-erp-3USEG6WL.js +3 -0
- package/dist/paid-order-erp-FSQ3GSXE.cjs +12 -0
- package/dist/pg-boss-service-4XF2TQ2E.js +2 -0
- package/dist/pg-boss-service-L6MTF4EQ.cjs +15 -0
- package/dist/razorpay-KLO2KNCB.js +49 -0
- package/dist/razorpay-U23LGY72.cjs +56 -0
- package/dist/rbac-debug-db-D7ME7QUY.cjs +35 -0
- package/dist/rbac-debug-db-MTCTVNNM.js +33 -0
- package/dist/sms-defaults-2NL24H57.js +2 -0
- package/dist/sms-defaults-KCOPKQBA.cjs +19 -0
- package/dist/stripe-4FD27QVJ.js +51 -0
- package/dist/stripe-VU6OEG2D.cjs +57 -0
- package/dist/theme.cjs +31 -59
- package/dist/theme.d.cts +78 -3
- package/dist/theme.d.ts +78 -3
- package/dist/theme.js +23 -20
- package/dist/vendor-invite-status-77O7ZQ3U.cjs +19 -0
- package/dist/vendor-invite-status-PWJ3DE76.js +2 -0
- package/dist/whatsapp-queue-3DXA4MXU.js +2 -0
- package/dist/whatsapp-queue-KG65MXD5.cjs +15 -0
- package/package.json +147 -142
- package/dist/admin.cjs.map +0 -1
- package/dist/admin.js.map +0 -1
- package/dist/api.cjs.map +0 -1
- package/dist/api.js.map +0 -1
- package/dist/auth.cjs.map +0 -1
- package/dist/auth.js.map +0 -1
- package/dist/cli.cjs.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/config-DJ5CmQvS.d.cts +0 -8
- package/dist/config-DJ5CmQvS.d.ts +0 -8
- package/dist/hooks.cjs.map +0 -1
- package/dist/hooks.js.map +0 -1
- package/dist/index-Bf5GO8fu.d.cts +0 -583
- package/dist/index-DOiJuMQA.d.ts +0 -583
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/theme.cjs.map +0 -1
- package/dist/theme.js.map +0 -1
- package/dist/types-DCVaXlPV.d.cts +0 -78
- package/dist/types-DCVaXlPV.d.ts +0 -78
- package/dist/vendor-scope-DTYhJk_I.d.cts +0 -129
- package/dist/vendor-scope-DTYhJk_I.d.ts +0 -129
package/dist/auth.d.cts
CHANGED
|
@@ -1,65 +1,99 @@
|
|
|
1
|
-
import { S as SessionUser, E as EntityCrudAction, b as EntityPermissionFlags } from './vendor-scope-DTYhJk_I.cjs';
|
|
2
|
-
export { A as ADMIN_GROUP_NAME, a as AuthHelpers, G as GetSession, O as OPEN_ENDPOINTS, P as PERMISSION_REQUIRED_ENDPOINTS, R as RBAC_ADMIN_ONLY_ENTITIES, V as VENDOR_OWNER_GROUP_NAME, c as VENDOR_SCOPED_STORE_ENTITIES, d as VENDOR_STORE_RBAC_ENTITIES, f as canManageRoles, g as canManageVendorRoles, h as canManageVendorTeam, i as canOnboardVendors, j as createAuthHelpers, k as createCmsAuthBundle, l as getPermissionableEntityKeys, m as getRequiredPermission, n as hasEntityPermission, o as isOpenEndpoint, p as isPlatformAdministrator, q as isPublicMethod, r as isSuperAdminGroupName, s as isVendorGroupName, t as isVendorOwner, u as isVendorPortalUser, v as isVendorStaff, w as permissionRowsToRecord, x as resolveVendorScopeFromSessionUser, y as sessionHasEntityAccess, z as vendorPortalFlagsFromUser } from './vendor-scope-DTYhJk_I.cjs';
|
|
3
1
|
import { DataSource } from 'typeorm';
|
|
4
2
|
import { getToken } from 'next-auth/jwt';
|
|
5
3
|
import { NextAuthOptions } from 'next-auth';
|
|
6
4
|
|
|
5
|
+
/** Canonical name for new installs / migrations */
|
|
6
|
+
declare const ADMIN_GROUP_NAME = "Administrator";
|
|
7
|
+
/** System administrator group (roles UI + users / user_groups / permissions bypass). */
|
|
8
|
+
declare function isSuperAdminGroupName(name: string | null | undefined): boolean;
|
|
9
|
+
type EntityCrudAction = 'create' | 'read' | 'update' | 'delete';
|
|
10
|
+
type EntityPermissionFlags = {
|
|
11
|
+
c: boolean;
|
|
12
|
+
r: boolean;
|
|
13
|
+
u: boolean;
|
|
14
|
+
d: boolean;
|
|
15
|
+
};
|
|
16
|
+
declare function getPermissionableEntityKeys(entityMap: Record<string, unknown>): string[];
|
|
17
|
+
declare function permissionRowsToRecord(rows: Array<{
|
|
18
|
+
entity: string;
|
|
19
|
+
canCreate: boolean;
|
|
20
|
+
canRead: boolean;
|
|
21
|
+
canUpdate: boolean;
|
|
22
|
+
canDelete: boolean;
|
|
23
|
+
}> | undefined): Record<string, EntityPermissionFlags>;
|
|
24
|
+
declare function hasEntityPermission(record: Record<string, EntityPermissionFlags> | undefined, entity: string, action: EntityCrudAction): boolean;
|
|
25
|
+
|
|
7
26
|
/**
|
|
8
|
-
*
|
|
27
|
+
* @deprecated Administrator bypass is now full entity access via `isRBACAdmin` in `sessionHasEntityAccess`.
|
|
28
|
+
* Kept for backwards-compatible imports.
|
|
9
29
|
*/
|
|
10
|
-
|
|
11
|
-
interface
|
|
12
|
-
id
|
|
13
|
-
email
|
|
14
|
-
name
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
30
|
+
declare const RBAC_ADMIN_ONLY_ENTITIES: Set<string>;
|
|
31
|
+
interface SessionUser {
|
|
32
|
+
id?: string;
|
|
33
|
+
email?: string | null;
|
|
34
|
+
name?: string | null;
|
|
35
|
+
groupId?: number;
|
|
36
|
+
/** User group display name (from login). */
|
|
37
|
+
groupName?: string | null;
|
|
38
|
+
/** @deprecated use entityPerms / isRBACAdmin */
|
|
39
|
+
permissions?: string[];
|
|
40
|
+
/** Administrator group: bypasses entity-level RBAC on all resources */
|
|
41
|
+
isRBACAdmin?: boolean;
|
|
42
|
+
entityPerms?: Record<string, EntityPermissionFlags>;
|
|
43
|
+
/** When false and not isRBACAdmin, admin API/UI is denied. */
|
|
19
44
|
adminAccess?: boolean;
|
|
20
|
-
|
|
21
|
-
name?: string;
|
|
22
|
-
permissions?: Array<{
|
|
23
|
-
entity: string;
|
|
24
|
-
canCreate: boolean;
|
|
25
|
-
canRead: boolean;
|
|
26
|
-
canUpdate: boolean;
|
|
27
|
-
canDelete: boolean;
|
|
28
|
-
}>;
|
|
29
|
-
};
|
|
45
|
+
/** Vendor stores this user can access (from vendor_users). */
|
|
30
46
|
vendorIds?: number[];
|
|
47
|
+
/** Active vendor for scoped CRUD (vendor staff). */
|
|
31
48
|
activeVendorId?: number | null;
|
|
49
|
+
/** Role for the active vendor link (`vendor_users.role`). */
|
|
32
50
|
vendorRole?: 'owner' | 'staff' | null;
|
|
51
|
+
/** Active vendor-scoped role id (`vendor_users.vendorRoleId`). */
|
|
52
|
+
vendorRoleId?: number | null;
|
|
53
|
+
vendorRoleName?: string | null;
|
|
54
|
+
/** True when active vendor role has `isOwnerRole`. */
|
|
55
|
+
isVendorRoleOwner?: boolean;
|
|
56
|
+
/** Permissions from active vendor role (`vendor_role_permissions`). */
|
|
57
|
+
vendorEntityPerms?: Record<string, EntityPermissionFlags>;
|
|
58
|
+
/** Set at login: vendor store portal (not platform admin). */
|
|
59
|
+
isVendorPortal?: boolean;
|
|
60
|
+
/** Set at login: vendor store owner (team + permissions). */
|
|
61
|
+
isVendorOwner?: boolean;
|
|
33
62
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
63
|
+
declare function sessionHasEntityAccess(user: SessionUser | null | undefined, entity: string, action: EntityCrudAction): boolean;
|
|
64
|
+
declare function canManageRoles(user: SessionUser | null | undefined): boolean;
|
|
65
|
+
type GetSession = () => Promise<{
|
|
66
|
+
user?: SessionUser;
|
|
67
|
+
} | null>;
|
|
68
|
+
declare const OPEN_ENDPOINTS: Array<Record<string, string[]>>;
|
|
69
|
+
declare const PERMISSION_REQUIRED_ENDPOINTS: Record<string, string[]>;
|
|
70
|
+
declare function isOpenEndpoint(pathname: string): boolean;
|
|
71
|
+
declare function getRequiredPermission(pathname: string): string[] | null;
|
|
72
|
+
declare function isPublicMethod(pathname: string, method: string): boolean;
|
|
73
|
+
interface AuthHelpers {
|
|
74
|
+
requireAuth(req: Request): Promise<Response | null>;
|
|
75
|
+
requirePermission(req: Request, permission: string): Promise<Response | null>;
|
|
76
|
+
requireEntityPermission(req: Request, entity: string, action: EntityCrudAction): Promise<Response | null>;
|
|
77
|
+
requireAdminAccess(req: Request): Promise<Response | null>;
|
|
78
|
+
getAuthenticatedUser(): Promise<SessionUser | null>;
|
|
38
79
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
* - omitted — auto: allow unless `callbackUrl` targets `/admin` (storefront `/signin` works unchanged)
|
|
57
|
-
*/
|
|
58
|
-
allowCustomerLogin?: boolean;
|
|
59
|
-
}
|
|
60
|
-
declare function getNextAuthOptions(config: NextAuthOptionsConfig): NextAuthOptions;
|
|
61
|
-
/** Storefront sign-in: allows Customer group; use with signInPage `/signin`. */
|
|
62
|
-
declare function getStorefrontNextAuthOptions(config: Omit<NextAuthOptionsConfig, 'allowCustomerLogin'>): NextAuthOptions;
|
|
80
|
+
declare function createAuthHelpers(getSession: GetSession, NextResponse: {
|
|
81
|
+
json: (body: unknown, init?: {
|
|
82
|
+
status?: number;
|
|
83
|
+
}) => Response;
|
|
84
|
+
}): AuthHelpers;
|
|
85
|
+
/** Pass return value into `createCmsApiHandler` (includes `getSessionUser` for vendor store APIs). */
|
|
86
|
+
declare function createCmsAuthBundle(getSession: GetSession, NextResponse: {
|
|
87
|
+
json: (body: unknown, init?: {
|
|
88
|
+
status?: number;
|
|
89
|
+
}) => Response;
|
|
90
|
+
}): {
|
|
91
|
+
requireAuth: (req: Request) => Promise<Response | null>;
|
|
92
|
+
requireAdminAccess: (req: Request) => Promise<Response | null>;
|
|
93
|
+
requireEntityPermission: (req: Request, entity: string, action: EntityCrudAction) => Promise<Response | null>;
|
|
94
|
+
getSessionUser: () => Promise<SessionUser | null>;
|
|
95
|
+
getAuthenticatedUser: () => Promise<SessionUser | null>;
|
|
96
|
+
};
|
|
63
97
|
|
|
64
98
|
/** Minimal DB handle for RBAC debug (avoids importing `typeorm` in the auth bundle). */
|
|
65
99
|
type RbacDebugDataSource = {
|
|
@@ -90,6 +124,49 @@ declare const VENDOR_ADMIN_GROUP_ID = 5;
|
|
|
90
124
|
declare function isSuperAdmin(user: SessionUser | null | undefined): boolean;
|
|
91
125
|
declare function isVendorAdmin(user: SessionUser | null | undefined): boolean;
|
|
92
126
|
|
|
127
|
+
/** Entities with a `vendorId` column (store data). */
|
|
128
|
+
declare const VENDOR_SCOPED_STORE_ENTITIES: Set<string>;
|
|
129
|
+
/**
|
|
130
|
+
* Store admin RBAC for vendor portal users (read/create/update/delete fallbacks in rbac-debug).
|
|
131
|
+
* Includes entities without `vendorId` that are still part of the store admin UI.
|
|
132
|
+
*/
|
|
133
|
+
declare const VENDOR_STORE_RBAC_ENTITIES: Set<string>;
|
|
134
|
+
type VendorScope = {
|
|
135
|
+
type: 'all';
|
|
136
|
+
} | {
|
|
137
|
+
type: 'vendor';
|
|
138
|
+
vendorId: number;
|
|
139
|
+
vendorIds: number[];
|
|
140
|
+
} | {
|
|
141
|
+
type: 'deny';
|
|
142
|
+
};
|
|
143
|
+
declare const VENDOR_OWNER_GROUP_NAME = "Vendor Owner";
|
|
144
|
+
/** User groups treated as vendor store staff (sidebar + scoped admin). */
|
|
145
|
+
declare function isVendorGroupName(name: string | null | undefined): boolean;
|
|
146
|
+
declare function isPlatformAdministrator(user: SessionUser | null | undefined): boolean;
|
|
147
|
+
/** Vendor portal UI (store + store admin), not platform admin. */
|
|
148
|
+
declare function isVendorPortalUser(user: SessionUser | null | undefined): boolean;
|
|
149
|
+
declare function isVendorStaff(user: SessionUser | null | undefined): boolean;
|
|
150
|
+
/** Vendor store owner (manages team + role permissions for their store). */
|
|
151
|
+
declare function isVendorOwner(user: SessionUser | null | undefined): boolean;
|
|
152
|
+
declare function canManageVendorTeam(user: SessionUser | null | undefined): boolean;
|
|
153
|
+
declare function canManageVendorRoles(user: SessionUser | null | undefined): boolean;
|
|
154
|
+
/** Platform admins (Administrator group) can onboard vendors. */
|
|
155
|
+
declare function canOnboardVendors(user: SessionUser | null | undefined): boolean;
|
|
156
|
+
declare function resolveVendorScopeFromSessionUser(user: SessionUser | null | undefined): VendorScope;
|
|
157
|
+
/** Compute portal flags at login (persist on JWT). */
|
|
158
|
+
declare function vendorPortalFlagsFromUser(input: {
|
|
159
|
+
email: string;
|
|
160
|
+
isRBACAdmin: boolean;
|
|
161
|
+
groupName?: string | null;
|
|
162
|
+
vendorIds?: number[];
|
|
163
|
+
vendorRole?: 'owner' | 'staff' | null;
|
|
164
|
+
isVendorRoleOwner?: boolean;
|
|
165
|
+
}): {
|
|
166
|
+
isVendorPortal: boolean;
|
|
167
|
+
isVendorOwner: boolean;
|
|
168
|
+
};
|
|
169
|
+
|
|
93
170
|
/**
|
|
94
171
|
* Ensures the Administrator group has full CRUD on every permissionable entity
|
|
95
172
|
* for the given entity map. Idempotent: upserts per entity.
|
|
@@ -154,4 +231,70 @@ declare function logAuthClient(message: string, data?: Record<string, unknown>):
|
|
|
154
231
|
declare function summarizeSessionUserForLog(user: unknown): Record<string, unknown>;
|
|
155
232
|
declare function nextAuthCookieDebugInfo(): Record<string, unknown>;
|
|
156
233
|
|
|
157
|
-
|
|
234
|
+
/**
|
|
235
|
+
* Build NextAuth options for credentials auth. App can extend/override via extend().
|
|
236
|
+
*/
|
|
237
|
+
|
|
238
|
+
interface NextAuthUser {
|
|
239
|
+
id: number;
|
|
240
|
+
email: string;
|
|
241
|
+
name: string | null;
|
|
242
|
+
password: string | null;
|
|
243
|
+
blocked?: boolean;
|
|
244
|
+
deleted?: boolean;
|
|
245
|
+
groupId?: number | null;
|
|
246
|
+
adminAccess?: boolean;
|
|
247
|
+
group?: {
|
|
248
|
+
name?: string;
|
|
249
|
+
permissions?: Array<{
|
|
250
|
+
entity: string;
|
|
251
|
+
canCreate: boolean;
|
|
252
|
+
canRead: boolean;
|
|
253
|
+
canUpdate: boolean;
|
|
254
|
+
canDelete: boolean;
|
|
255
|
+
}>;
|
|
256
|
+
};
|
|
257
|
+
vendorIds?: number[];
|
|
258
|
+
activeVendorId?: number | null;
|
|
259
|
+
vendorRole?: 'owner' | 'staff' | null;
|
|
260
|
+
vendorRoleId?: number | null;
|
|
261
|
+
vendorRoleName?: string | null;
|
|
262
|
+
isVendorRoleOwner?: boolean;
|
|
263
|
+
vendorEntityPerms?: Record<string, {
|
|
264
|
+
c: boolean;
|
|
265
|
+
r: boolean;
|
|
266
|
+
u: boolean;
|
|
267
|
+
d: boolean;
|
|
268
|
+
}>;
|
|
269
|
+
}
|
|
270
|
+
interface AuthorizeOtpInput {
|
|
271
|
+
identifier: string;
|
|
272
|
+
channel: 'email' | 'sms';
|
|
273
|
+
code: string;
|
|
274
|
+
}
|
|
275
|
+
interface NextAuthOptionsConfig {
|
|
276
|
+
/** Resolve user by email (e.g. from TypeORM). Return null if not found. */
|
|
277
|
+
getUserByEmail: (email: string) => Promise<NextAuthUser | null>;
|
|
278
|
+
comparePassword: (plain: string, hash: string) => Promise<boolean>;
|
|
279
|
+
signInPage?: string;
|
|
280
|
+
secret?: string;
|
|
281
|
+
extend?: (options: NextAuthOptions) => NextAuthOptions;
|
|
282
|
+
/** When false, password CredentialsProvider is omitted. Default true. */
|
|
283
|
+
enablePasswordLogin?: boolean;
|
|
284
|
+
/** When true, registers CredentialsProvider id `otp`. Requires authorizeOtp. Default false. */
|
|
285
|
+
enableOtpLogin?: boolean;
|
|
286
|
+
/** Validate OTP and return user (same shape as password flow) or null. */
|
|
287
|
+
authorizeOtp?: (input: AuthorizeOtpInput) => Promise<NextAuthUser | null>;
|
|
288
|
+
/**
|
|
289
|
+
* Customer group sign-in policy for credentials/OTP on a shared `/api/auth` route:
|
|
290
|
+
* - `true` — always allow (dedicated storefront auth)
|
|
291
|
+
* - `false` — always block
|
|
292
|
+
* - omitted — auto: allow unless `callbackUrl` targets `/admin` (storefront `/signin` works unchanged)
|
|
293
|
+
*/
|
|
294
|
+
allowCustomerLogin?: boolean;
|
|
295
|
+
}
|
|
296
|
+
declare function getNextAuthOptions(config: NextAuthOptionsConfig): NextAuthOptions;
|
|
297
|
+
/** Storefront sign-in: allows Customer group; use with signInPage `/signin`. */
|
|
298
|
+
declare function getStorefrontNextAuthOptions(config: Omit<NextAuthOptionsConfig, 'allowCustomerLogin'>): NextAuthOptions;
|
|
299
|
+
|
|
300
|
+
export { ADMIN_GROUP_NAME, type AuthHelpers, type AuthorizeOtpInput, type CmsMiddlewareConfig, type CmsMiddlewareRequest, type EntityCrudAction, type EntityPermissionFlags, type GetSession, type NextAuthOptionsConfig, type NextAuthUser, OPEN_ENDPOINTS, PERMISSION_REQUIRED_ENDPOINTS, RBAC_ADMIN_ONLY_ENTITIES, SUPER_ADMIN_GROUP_ID, type SessionUser, VENDOR_ADMIN_GROUP_ID, VENDOR_OWNER_GROUP_NAME, VENDOR_SCOPED_STORE_ENTITIES, VENDOR_STORE_RBAC_ENTITIES, canManageRoles, canManageVendorRoles, canManageVendorTeam, canOnboardVendors, createAuthHelpers, createCmsAuthBundle, createCmsMiddleware, defaultPublicApiMethods, explainSessionEntityAccess, getNextAuthOptions, getPermissionableEntityKeys, getRequiredPermission, getStorefrontNextAuthOptions, hasEntityPermission, isAuthDebugClientEnabled, isAuthDebugEnabled, isOpenEndpoint, isPlatformAdministrator, isPublicMethod, isRbacDebugEnabled, isSuperAdmin, isSuperAdminGroupName, isVendorAdmin, isVendorGroupName, isVendorOwner, isVendorPortalUser, isVendorStaff, logAuth, logAuthClient, logEntityAccessDecision, logRbac, nextAuthCookieDebugInfo, permissionRowsToRecord, resolveVendorScopeFromSessionUser, seedAdministratorPermissions, sessionHasEntityAccess, summarizeEntityPerms, summarizeSessionUserForLog, vendorPortalFlagsFromUser };
|
package/dist/auth.d.ts
CHANGED
|
@@ -1,65 +1,99 @@
|
|
|
1
|
-
import { S as SessionUser, E as EntityCrudAction, b as EntityPermissionFlags } from './vendor-scope-DTYhJk_I.js';
|
|
2
|
-
export { A as ADMIN_GROUP_NAME, a as AuthHelpers, G as GetSession, O as OPEN_ENDPOINTS, P as PERMISSION_REQUIRED_ENDPOINTS, R as RBAC_ADMIN_ONLY_ENTITIES, V as VENDOR_OWNER_GROUP_NAME, c as VENDOR_SCOPED_STORE_ENTITIES, d as VENDOR_STORE_RBAC_ENTITIES, f as canManageRoles, g as canManageVendorRoles, h as canManageVendorTeam, i as canOnboardVendors, j as createAuthHelpers, k as createCmsAuthBundle, l as getPermissionableEntityKeys, m as getRequiredPermission, n as hasEntityPermission, o as isOpenEndpoint, p as isPlatformAdministrator, q as isPublicMethod, r as isSuperAdminGroupName, s as isVendorGroupName, t as isVendorOwner, u as isVendorPortalUser, v as isVendorStaff, w as permissionRowsToRecord, x as resolveVendorScopeFromSessionUser, y as sessionHasEntityAccess, z as vendorPortalFlagsFromUser } from './vendor-scope-DTYhJk_I.js';
|
|
3
1
|
import { DataSource } from 'typeorm';
|
|
4
2
|
import { getToken } from 'next-auth/jwt';
|
|
5
3
|
import { NextAuthOptions } from 'next-auth';
|
|
6
4
|
|
|
5
|
+
/** Canonical name for new installs / migrations */
|
|
6
|
+
declare const ADMIN_GROUP_NAME = "Administrator";
|
|
7
|
+
/** System administrator group (roles UI + users / user_groups / permissions bypass). */
|
|
8
|
+
declare function isSuperAdminGroupName(name: string | null | undefined): boolean;
|
|
9
|
+
type EntityCrudAction = 'create' | 'read' | 'update' | 'delete';
|
|
10
|
+
type EntityPermissionFlags = {
|
|
11
|
+
c: boolean;
|
|
12
|
+
r: boolean;
|
|
13
|
+
u: boolean;
|
|
14
|
+
d: boolean;
|
|
15
|
+
};
|
|
16
|
+
declare function getPermissionableEntityKeys(entityMap: Record<string, unknown>): string[];
|
|
17
|
+
declare function permissionRowsToRecord(rows: Array<{
|
|
18
|
+
entity: string;
|
|
19
|
+
canCreate: boolean;
|
|
20
|
+
canRead: boolean;
|
|
21
|
+
canUpdate: boolean;
|
|
22
|
+
canDelete: boolean;
|
|
23
|
+
}> | undefined): Record<string, EntityPermissionFlags>;
|
|
24
|
+
declare function hasEntityPermission(record: Record<string, EntityPermissionFlags> | undefined, entity: string, action: EntityCrudAction): boolean;
|
|
25
|
+
|
|
7
26
|
/**
|
|
8
|
-
*
|
|
27
|
+
* @deprecated Administrator bypass is now full entity access via `isRBACAdmin` in `sessionHasEntityAccess`.
|
|
28
|
+
* Kept for backwards-compatible imports.
|
|
9
29
|
*/
|
|
10
|
-
|
|
11
|
-
interface
|
|
12
|
-
id
|
|
13
|
-
email
|
|
14
|
-
name
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
30
|
+
declare const RBAC_ADMIN_ONLY_ENTITIES: Set<string>;
|
|
31
|
+
interface SessionUser {
|
|
32
|
+
id?: string;
|
|
33
|
+
email?: string | null;
|
|
34
|
+
name?: string | null;
|
|
35
|
+
groupId?: number;
|
|
36
|
+
/** User group display name (from login). */
|
|
37
|
+
groupName?: string | null;
|
|
38
|
+
/** @deprecated use entityPerms / isRBACAdmin */
|
|
39
|
+
permissions?: string[];
|
|
40
|
+
/** Administrator group: bypasses entity-level RBAC on all resources */
|
|
41
|
+
isRBACAdmin?: boolean;
|
|
42
|
+
entityPerms?: Record<string, EntityPermissionFlags>;
|
|
43
|
+
/** When false and not isRBACAdmin, admin API/UI is denied. */
|
|
19
44
|
adminAccess?: boolean;
|
|
20
|
-
|
|
21
|
-
name?: string;
|
|
22
|
-
permissions?: Array<{
|
|
23
|
-
entity: string;
|
|
24
|
-
canCreate: boolean;
|
|
25
|
-
canRead: boolean;
|
|
26
|
-
canUpdate: boolean;
|
|
27
|
-
canDelete: boolean;
|
|
28
|
-
}>;
|
|
29
|
-
};
|
|
45
|
+
/** Vendor stores this user can access (from vendor_users). */
|
|
30
46
|
vendorIds?: number[];
|
|
47
|
+
/** Active vendor for scoped CRUD (vendor staff). */
|
|
31
48
|
activeVendorId?: number | null;
|
|
49
|
+
/** Role for the active vendor link (`vendor_users.role`). */
|
|
32
50
|
vendorRole?: 'owner' | 'staff' | null;
|
|
51
|
+
/** Active vendor-scoped role id (`vendor_users.vendorRoleId`). */
|
|
52
|
+
vendorRoleId?: number | null;
|
|
53
|
+
vendorRoleName?: string | null;
|
|
54
|
+
/** True when active vendor role has `isOwnerRole`. */
|
|
55
|
+
isVendorRoleOwner?: boolean;
|
|
56
|
+
/** Permissions from active vendor role (`vendor_role_permissions`). */
|
|
57
|
+
vendorEntityPerms?: Record<string, EntityPermissionFlags>;
|
|
58
|
+
/** Set at login: vendor store portal (not platform admin). */
|
|
59
|
+
isVendorPortal?: boolean;
|
|
60
|
+
/** Set at login: vendor store owner (team + permissions). */
|
|
61
|
+
isVendorOwner?: boolean;
|
|
33
62
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
63
|
+
declare function sessionHasEntityAccess(user: SessionUser | null | undefined, entity: string, action: EntityCrudAction): boolean;
|
|
64
|
+
declare function canManageRoles(user: SessionUser | null | undefined): boolean;
|
|
65
|
+
type GetSession = () => Promise<{
|
|
66
|
+
user?: SessionUser;
|
|
67
|
+
} | null>;
|
|
68
|
+
declare const OPEN_ENDPOINTS: Array<Record<string, string[]>>;
|
|
69
|
+
declare const PERMISSION_REQUIRED_ENDPOINTS: Record<string, string[]>;
|
|
70
|
+
declare function isOpenEndpoint(pathname: string): boolean;
|
|
71
|
+
declare function getRequiredPermission(pathname: string): string[] | null;
|
|
72
|
+
declare function isPublicMethod(pathname: string, method: string): boolean;
|
|
73
|
+
interface AuthHelpers {
|
|
74
|
+
requireAuth(req: Request): Promise<Response | null>;
|
|
75
|
+
requirePermission(req: Request, permission: string): Promise<Response | null>;
|
|
76
|
+
requireEntityPermission(req: Request, entity: string, action: EntityCrudAction): Promise<Response | null>;
|
|
77
|
+
requireAdminAccess(req: Request): Promise<Response | null>;
|
|
78
|
+
getAuthenticatedUser(): Promise<SessionUser | null>;
|
|
38
79
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
* - omitted — auto: allow unless `callbackUrl` targets `/admin` (storefront `/signin` works unchanged)
|
|
57
|
-
*/
|
|
58
|
-
allowCustomerLogin?: boolean;
|
|
59
|
-
}
|
|
60
|
-
declare function getNextAuthOptions(config: NextAuthOptionsConfig): NextAuthOptions;
|
|
61
|
-
/** Storefront sign-in: allows Customer group; use with signInPage `/signin`. */
|
|
62
|
-
declare function getStorefrontNextAuthOptions(config: Omit<NextAuthOptionsConfig, 'allowCustomerLogin'>): NextAuthOptions;
|
|
80
|
+
declare function createAuthHelpers(getSession: GetSession, NextResponse: {
|
|
81
|
+
json: (body: unknown, init?: {
|
|
82
|
+
status?: number;
|
|
83
|
+
}) => Response;
|
|
84
|
+
}): AuthHelpers;
|
|
85
|
+
/** Pass return value into `createCmsApiHandler` (includes `getSessionUser` for vendor store APIs). */
|
|
86
|
+
declare function createCmsAuthBundle(getSession: GetSession, NextResponse: {
|
|
87
|
+
json: (body: unknown, init?: {
|
|
88
|
+
status?: number;
|
|
89
|
+
}) => Response;
|
|
90
|
+
}): {
|
|
91
|
+
requireAuth: (req: Request) => Promise<Response | null>;
|
|
92
|
+
requireAdminAccess: (req: Request) => Promise<Response | null>;
|
|
93
|
+
requireEntityPermission: (req: Request, entity: string, action: EntityCrudAction) => Promise<Response | null>;
|
|
94
|
+
getSessionUser: () => Promise<SessionUser | null>;
|
|
95
|
+
getAuthenticatedUser: () => Promise<SessionUser | null>;
|
|
96
|
+
};
|
|
63
97
|
|
|
64
98
|
/** Minimal DB handle for RBAC debug (avoids importing `typeorm` in the auth bundle). */
|
|
65
99
|
type RbacDebugDataSource = {
|
|
@@ -90,6 +124,49 @@ declare const VENDOR_ADMIN_GROUP_ID = 5;
|
|
|
90
124
|
declare function isSuperAdmin(user: SessionUser | null | undefined): boolean;
|
|
91
125
|
declare function isVendorAdmin(user: SessionUser | null | undefined): boolean;
|
|
92
126
|
|
|
127
|
+
/** Entities with a `vendorId` column (store data). */
|
|
128
|
+
declare const VENDOR_SCOPED_STORE_ENTITIES: Set<string>;
|
|
129
|
+
/**
|
|
130
|
+
* Store admin RBAC for vendor portal users (read/create/update/delete fallbacks in rbac-debug).
|
|
131
|
+
* Includes entities without `vendorId` that are still part of the store admin UI.
|
|
132
|
+
*/
|
|
133
|
+
declare const VENDOR_STORE_RBAC_ENTITIES: Set<string>;
|
|
134
|
+
type VendorScope = {
|
|
135
|
+
type: 'all';
|
|
136
|
+
} | {
|
|
137
|
+
type: 'vendor';
|
|
138
|
+
vendorId: number;
|
|
139
|
+
vendorIds: number[];
|
|
140
|
+
} | {
|
|
141
|
+
type: 'deny';
|
|
142
|
+
};
|
|
143
|
+
declare const VENDOR_OWNER_GROUP_NAME = "Vendor Owner";
|
|
144
|
+
/** User groups treated as vendor store staff (sidebar + scoped admin). */
|
|
145
|
+
declare function isVendorGroupName(name: string | null | undefined): boolean;
|
|
146
|
+
declare function isPlatformAdministrator(user: SessionUser | null | undefined): boolean;
|
|
147
|
+
/** Vendor portal UI (store + store admin), not platform admin. */
|
|
148
|
+
declare function isVendorPortalUser(user: SessionUser | null | undefined): boolean;
|
|
149
|
+
declare function isVendorStaff(user: SessionUser | null | undefined): boolean;
|
|
150
|
+
/** Vendor store owner (manages team + role permissions for their store). */
|
|
151
|
+
declare function isVendorOwner(user: SessionUser | null | undefined): boolean;
|
|
152
|
+
declare function canManageVendorTeam(user: SessionUser | null | undefined): boolean;
|
|
153
|
+
declare function canManageVendorRoles(user: SessionUser | null | undefined): boolean;
|
|
154
|
+
/** Platform admins (Administrator group) can onboard vendors. */
|
|
155
|
+
declare function canOnboardVendors(user: SessionUser | null | undefined): boolean;
|
|
156
|
+
declare function resolveVendorScopeFromSessionUser(user: SessionUser | null | undefined): VendorScope;
|
|
157
|
+
/** Compute portal flags at login (persist on JWT). */
|
|
158
|
+
declare function vendorPortalFlagsFromUser(input: {
|
|
159
|
+
email: string;
|
|
160
|
+
isRBACAdmin: boolean;
|
|
161
|
+
groupName?: string | null;
|
|
162
|
+
vendorIds?: number[];
|
|
163
|
+
vendorRole?: 'owner' | 'staff' | null;
|
|
164
|
+
isVendorRoleOwner?: boolean;
|
|
165
|
+
}): {
|
|
166
|
+
isVendorPortal: boolean;
|
|
167
|
+
isVendorOwner: boolean;
|
|
168
|
+
};
|
|
169
|
+
|
|
93
170
|
/**
|
|
94
171
|
* Ensures the Administrator group has full CRUD on every permissionable entity
|
|
95
172
|
* for the given entity map. Idempotent: upserts per entity.
|
|
@@ -154,4 +231,70 @@ declare function logAuthClient(message: string, data?: Record<string, unknown>):
|
|
|
154
231
|
declare function summarizeSessionUserForLog(user: unknown): Record<string, unknown>;
|
|
155
232
|
declare function nextAuthCookieDebugInfo(): Record<string, unknown>;
|
|
156
233
|
|
|
157
|
-
|
|
234
|
+
/**
|
|
235
|
+
* Build NextAuth options for credentials auth. App can extend/override via extend().
|
|
236
|
+
*/
|
|
237
|
+
|
|
238
|
+
interface NextAuthUser {
|
|
239
|
+
id: number;
|
|
240
|
+
email: string;
|
|
241
|
+
name: string | null;
|
|
242
|
+
password: string | null;
|
|
243
|
+
blocked?: boolean;
|
|
244
|
+
deleted?: boolean;
|
|
245
|
+
groupId?: number | null;
|
|
246
|
+
adminAccess?: boolean;
|
|
247
|
+
group?: {
|
|
248
|
+
name?: string;
|
|
249
|
+
permissions?: Array<{
|
|
250
|
+
entity: string;
|
|
251
|
+
canCreate: boolean;
|
|
252
|
+
canRead: boolean;
|
|
253
|
+
canUpdate: boolean;
|
|
254
|
+
canDelete: boolean;
|
|
255
|
+
}>;
|
|
256
|
+
};
|
|
257
|
+
vendorIds?: number[];
|
|
258
|
+
activeVendorId?: number | null;
|
|
259
|
+
vendorRole?: 'owner' | 'staff' | null;
|
|
260
|
+
vendorRoleId?: number | null;
|
|
261
|
+
vendorRoleName?: string | null;
|
|
262
|
+
isVendorRoleOwner?: boolean;
|
|
263
|
+
vendorEntityPerms?: Record<string, {
|
|
264
|
+
c: boolean;
|
|
265
|
+
r: boolean;
|
|
266
|
+
u: boolean;
|
|
267
|
+
d: boolean;
|
|
268
|
+
}>;
|
|
269
|
+
}
|
|
270
|
+
interface AuthorizeOtpInput {
|
|
271
|
+
identifier: string;
|
|
272
|
+
channel: 'email' | 'sms';
|
|
273
|
+
code: string;
|
|
274
|
+
}
|
|
275
|
+
interface NextAuthOptionsConfig {
|
|
276
|
+
/** Resolve user by email (e.g. from TypeORM). Return null if not found. */
|
|
277
|
+
getUserByEmail: (email: string) => Promise<NextAuthUser | null>;
|
|
278
|
+
comparePassword: (plain: string, hash: string) => Promise<boolean>;
|
|
279
|
+
signInPage?: string;
|
|
280
|
+
secret?: string;
|
|
281
|
+
extend?: (options: NextAuthOptions) => NextAuthOptions;
|
|
282
|
+
/** When false, password CredentialsProvider is omitted. Default true. */
|
|
283
|
+
enablePasswordLogin?: boolean;
|
|
284
|
+
/** When true, registers CredentialsProvider id `otp`. Requires authorizeOtp. Default false. */
|
|
285
|
+
enableOtpLogin?: boolean;
|
|
286
|
+
/** Validate OTP and return user (same shape as password flow) or null. */
|
|
287
|
+
authorizeOtp?: (input: AuthorizeOtpInput) => Promise<NextAuthUser | null>;
|
|
288
|
+
/**
|
|
289
|
+
* Customer group sign-in policy for credentials/OTP on a shared `/api/auth` route:
|
|
290
|
+
* - `true` — always allow (dedicated storefront auth)
|
|
291
|
+
* - `false` — always block
|
|
292
|
+
* - omitted — auto: allow unless `callbackUrl` targets `/admin` (storefront `/signin` works unchanged)
|
|
293
|
+
*/
|
|
294
|
+
allowCustomerLogin?: boolean;
|
|
295
|
+
}
|
|
296
|
+
declare function getNextAuthOptions(config: NextAuthOptionsConfig): NextAuthOptions;
|
|
297
|
+
/** Storefront sign-in: allows Customer group; use with signInPage `/signin`. */
|
|
298
|
+
declare function getStorefrontNextAuthOptions(config: Omit<NextAuthOptionsConfig, 'allowCustomerLogin'>): NextAuthOptions;
|
|
299
|
+
|
|
300
|
+
export { ADMIN_GROUP_NAME, type AuthHelpers, type AuthorizeOtpInput, type CmsMiddlewareConfig, type CmsMiddlewareRequest, type EntityCrudAction, type EntityPermissionFlags, type GetSession, type NextAuthOptionsConfig, type NextAuthUser, OPEN_ENDPOINTS, PERMISSION_REQUIRED_ENDPOINTS, RBAC_ADMIN_ONLY_ENTITIES, SUPER_ADMIN_GROUP_ID, type SessionUser, VENDOR_ADMIN_GROUP_ID, VENDOR_OWNER_GROUP_NAME, VENDOR_SCOPED_STORE_ENTITIES, VENDOR_STORE_RBAC_ENTITIES, canManageRoles, canManageVendorRoles, canManageVendorTeam, canOnboardVendors, createAuthHelpers, createCmsAuthBundle, createCmsMiddleware, defaultPublicApiMethods, explainSessionEntityAccess, getNextAuthOptions, getPermissionableEntityKeys, getRequiredPermission, getStorefrontNextAuthOptions, hasEntityPermission, isAuthDebugClientEnabled, isAuthDebugEnabled, isOpenEndpoint, isPlatformAdministrator, isPublicMethod, isRbacDebugEnabled, isSuperAdmin, isSuperAdminGroupName, isVendorAdmin, isVendorGroupName, isVendorOwner, isVendorPortalUser, isVendorStaff, logAuth, logAuthClient, logEntityAccessDecision, logRbac, nextAuthCookieDebugInfo, permissionRowsToRecord, resolveVendorScopeFromSessionUser, seedAdministratorPermissions, sessionHasEntityAccess, summarizeEntityPerms, summarizeSessionUserForLog, vendorPortalFlagsFromUser };
|