@timardex/cluemart-shared 1.5.824 → 1.5.827

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.
Files changed (60) hide show
  1. package/dist/{ad-BFGA6SrQ.d.ts → ad-CCm6QYXb.d.ts} +1 -1
  2. package/dist/{ad-BRC6KNgv.d.mts → ad-CZBOdoLr.d.mts} +1 -1
  3. package/dist/auth/index.cjs +202 -9
  4. package/dist/auth/index.cjs.map +1 -1
  5. package/dist/auth/index.d.mts +28 -3
  6. package/dist/auth/index.d.ts +28 -3
  7. package/dist/auth/index.mjs +49 -10
  8. package/dist/auth/index.mjs.map +1 -1
  9. package/dist/{chunk-N7KENXCS.mjs → chunk-4NGXTQWT.mjs} +3 -3
  10. package/dist/{chunk-IREUJYMR.mjs → chunk-AQR53ECY.mjs} +3 -3
  11. package/dist/chunk-GHW3ZGBY.mjs +168 -0
  12. package/dist/chunk-GHW3ZGBY.mjs.map +1 -0
  13. package/dist/{chunk-WZPKYUSX.mjs → chunk-MOB5R5BF.mjs} +2 -2
  14. package/dist/{chunk-MIDSLTUJ.mjs → chunk-UOFI3LKZ.mjs} +3 -2
  15. package/dist/chunk-UOFI3LKZ.mjs.map +1 -0
  16. package/dist/{chunk-UHDYJBIX.mjs → chunk-VNF22ITY.mjs} +2 -2
  17. package/dist/{chunk-D33VEY7Q.mjs → chunk-VR3TDBJL.mjs} +6 -6
  18. package/dist/chunk-VR3TDBJL.mjs.map +1 -0
  19. package/dist/{chunk-EUOLQ7SS.mjs → chunk-Y62E7JLT.mjs} +2 -2
  20. package/dist/enums/index.cjs +5 -5
  21. package/dist/enums/index.cjs.map +1 -1
  22. package/dist/enums/index.d.mts +6 -6
  23. package/dist/enums/index.d.ts +6 -6
  24. package/dist/enums/index.mjs +1 -1
  25. package/dist/formFields/index.cjs.map +1 -1
  26. package/dist/formFields/index.mjs +4 -4
  27. package/dist/graphql/index.cjs +2 -1
  28. package/dist/graphql/index.cjs.map +1 -1
  29. package/dist/graphql/index.d.mts +2 -2
  30. package/dist/graphql/index.d.ts +2 -2
  31. package/dist/graphql/index.mjs +3 -3
  32. package/dist/hooks/index.cjs +52 -19
  33. package/dist/hooks/index.cjs.map +1 -1
  34. package/dist/hooks/index.d.mts +2 -2
  35. package/dist/hooks/index.d.ts +2 -2
  36. package/dist/hooks/index.mjs +10 -15
  37. package/dist/hooks/index.mjs.map +1 -1
  38. package/dist/index.cjs +182 -6
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.d.mts +39 -8
  41. package/dist/index.d.ts +39 -8
  42. package/dist/index.mjs +172 -6
  43. package/dist/index.mjs.map +1 -1
  44. package/dist/sharing/index.cjs.map +1 -1
  45. package/dist/sharing/index.mjs +3 -3
  46. package/dist/types/index.d.mts +2 -2
  47. package/dist/types/index.d.ts +2 -2
  48. package/dist/types/index.mjs +1 -1
  49. package/dist/{user-CCN2IPDV.d.ts → user-IVhCYYTM.d.ts} +13 -3
  50. package/dist/{user-CadKvubI.d.mts → user-duZdr5Nn.d.mts} +13 -3
  51. package/dist/utils/index.cjs.map +1 -1
  52. package/dist/utils/index.mjs +3 -3
  53. package/package.json +1 -1
  54. package/dist/chunk-D33VEY7Q.mjs.map +0 -1
  55. package/dist/chunk-MIDSLTUJ.mjs.map +0 -1
  56. /package/dist/{chunk-N7KENXCS.mjs.map → chunk-4NGXTQWT.mjs.map} +0 -0
  57. /package/dist/{chunk-IREUJYMR.mjs.map → chunk-AQR53ECY.mjs.map} +0 -0
  58. /package/dist/{chunk-WZPKYUSX.mjs.map → chunk-MOB5R5BF.mjs.map} +0 -0
  59. /package/dist/{chunk-UHDYJBIX.mjs.map → chunk-VNF22ITY.mjs.map} +0 -0
  60. /package/dist/{chunk-EUOLQ7SS.mjs.map → chunk-Y62E7JLT.mjs.map} +0 -0
@@ -1,5 +1,6 @@
1
- import { EnumResourceType, EnumUserLicence } from '../enums/index.mjs';
2
- import { S as SafeUserType } from '../user-CadKvubI.mjs';
1
+ import { EnumUserRole, EnumResourceType, EnumUserLicence } from '../enums/index.mjs';
2
+ import { P as Permission, S as SafeUserType } from '../user-duZdr5Nn.mjs';
3
+ export { a as PERMISSIONS, W as WILDCARD_PERMISSION } from '../user-duZdr5Nn.mjs';
3
4
  import { T as Tier } from '../subscription-bmAdrnfi.mjs';
4
5
  import React, { ReactNode } from 'react';
5
6
  import '../global-959zf6qy.mjs';
@@ -23,6 +24,27 @@ type AuthManager = {
23
24
  */
24
25
  declare function createAuthManager(): AuthManager;
25
26
 
27
+ /**
28
+ * Union of permissions for the given roles (deduped, stable order).
29
+ */
30
+ declare function getPermissionsForRoles(roles: EnumUserRole[] | null | undefined): Permission[];
31
+ /**
32
+ * Check a concrete permission list (e.g. authUser.permissions) for a grant.
33
+ * Honours the "*" wildcard.
34
+ */
35
+ declare function permissionListIncludes(permissions: readonly Permission[] | null | undefined, permission: Permission): boolean;
36
+ declare function hasPermission(roles: EnumUserRole[] | null | undefined, permission: Permission): boolean;
37
+ declare function hasAnyPermission(roles: EnumUserRole[] | null | undefined, permissions: readonly Permission[]): boolean;
38
+ declare function hasAllPermissions(roles: EnumUserRole[] | null | undefined, permissions: readonly Permission[]): boolean;
39
+ declare function hasRole(roles: EnumUserRole[] | null | undefined, role: EnumUserRole): boolean;
40
+ declare function hasAnyRole(roles: EnumUserRole[] | null | undefined, checkRoles: readonly EnumUserRole[]): boolean;
41
+
42
+ /**
43
+ * Static role → permissions map. Source of truth for access.
44
+ * Permissions for a user = union of all their roles' lists.
45
+ */
46
+ declare const ROLE_PERMISSIONS: Record<EnumUserRole, readonly Permission[]>;
47
+
26
48
  type LimitType = "availability" | "images" | "calendar" | "associates" | "posters" | "productsList" | "statistics" | "relationShare";
27
49
  interface RoleLicences {
28
50
  pro_plus: boolean;
@@ -77,11 +99,14 @@ interface UseAuthReturnType {
77
99
  handleLogoutExplicit: () => Promise<void>;
78
100
  hasEventLicence: HasLicenceResult;
79
101
  hasPartnerLicence: HasLicenceResult;
102
+ hasPermission: (permission: Permission) => boolean;
103
+ hasRole: (role: EnumUserRole) => boolean;
80
104
  hasUserLicence: (licenceType: EnumUserLicence) => boolean;
81
105
  hasVendorLicence: HasLicenceResult;
82
106
  isAdmin: boolean;
83
107
  isSuperAdmin: boolean;
84
108
  isLoading: boolean;
109
+ permissions: Permission[];
85
110
  getLicenseAccessLevel: (limitType: LimitType, resourceId: string, resourceType: EnumResourceType) => number;
86
111
  refetchUser: () => Promise<void>;
87
112
  setUser: (user: SafeUserType | null) => Promise<void>;
@@ -116,4 +141,4 @@ declare const UserProvider: React.FC<{
116
141
  }>;
117
142
  declare const useAuthUser: () => UseAuthReturnType;
118
143
 
119
- export { type AuthManager, type AuthManagerLike, type AuthStorageAdapter, DEFAULT_LIMITS, type HasLicenceResult, type LicencedResourceType, type LicencesByRole, type LimitType, type LogoutReason, type ProfileBadgeLicence, type RoleLicences, SUPER_ADMIN_EMAIL, type UseAuthCoreAdapters, type UseAuthReturnType, UserProvider, createAuthManager, getLicenceFlagsByRole, hasLicence, hasUserLicenceType, isLicencedResourceType, isProfileBadgeLicence, useAuthCore, useAuthUser };
144
+ export { type AuthManager, type AuthManagerLike, type AuthStorageAdapter, DEFAULT_LIMITS, type HasLicenceResult, type LicencedResourceType, type LicencesByRole, type LimitType, type LogoutReason, Permission, type ProfileBadgeLicence, ROLE_PERMISSIONS, type RoleLicences, SUPER_ADMIN_EMAIL, type UseAuthCoreAdapters, type UseAuthReturnType, UserProvider, createAuthManager, getLicenceFlagsByRole, getPermissionsForRoles, hasAllPermissions, hasAnyPermission, hasAnyRole, hasLicence, hasPermission, hasRole, hasUserLicenceType, isLicencedResourceType, isProfileBadgeLicence, permissionListIncludes, useAuthCore, useAuthUser };
@@ -1,5 +1,6 @@
1
- import { EnumResourceType, EnumUserLicence } from '../enums/index.js';
2
- import { S as SafeUserType } from '../user-CCN2IPDV.js';
1
+ import { EnumUserRole, EnumResourceType, EnumUserLicence } from '../enums/index.js';
2
+ import { P as Permission, S as SafeUserType } from '../user-IVhCYYTM.js';
3
+ export { a as PERMISSIONS, W as WILDCARD_PERMISSION } from '../user-IVhCYYTM.js';
3
4
  import { T as Tier } from '../subscription-BU8GvH2K.js';
4
5
  import React, { ReactNode } from 'react';
5
6
  import '../global-wVC9VaCx.js';
@@ -23,6 +24,27 @@ type AuthManager = {
23
24
  */
24
25
  declare function createAuthManager(): AuthManager;
25
26
 
27
+ /**
28
+ * Union of permissions for the given roles (deduped, stable order).
29
+ */
30
+ declare function getPermissionsForRoles(roles: EnumUserRole[] | null | undefined): Permission[];
31
+ /**
32
+ * Check a concrete permission list (e.g. authUser.permissions) for a grant.
33
+ * Honours the "*" wildcard.
34
+ */
35
+ declare function permissionListIncludes(permissions: readonly Permission[] | null | undefined, permission: Permission): boolean;
36
+ declare function hasPermission(roles: EnumUserRole[] | null | undefined, permission: Permission): boolean;
37
+ declare function hasAnyPermission(roles: EnumUserRole[] | null | undefined, permissions: readonly Permission[]): boolean;
38
+ declare function hasAllPermissions(roles: EnumUserRole[] | null | undefined, permissions: readonly Permission[]): boolean;
39
+ declare function hasRole(roles: EnumUserRole[] | null | undefined, role: EnumUserRole): boolean;
40
+ declare function hasAnyRole(roles: EnumUserRole[] | null | undefined, checkRoles: readonly EnumUserRole[]): boolean;
41
+
42
+ /**
43
+ * Static role → permissions map. Source of truth for access.
44
+ * Permissions for a user = union of all their roles' lists.
45
+ */
46
+ declare const ROLE_PERMISSIONS: Record<EnumUserRole, readonly Permission[]>;
47
+
26
48
  type LimitType = "availability" | "images" | "calendar" | "associates" | "posters" | "productsList" | "statistics" | "relationShare";
27
49
  interface RoleLicences {
28
50
  pro_plus: boolean;
@@ -77,11 +99,14 @@ interface UseAuthReturnType {
77
99
  handleLogoutExplicit: () => Promise<void>;
78
100
  hasEventLicence: HasLicenceResult;
79
101
  hasPartnerLicence: HasLicenceResult;
102
+ hasPermission: (permission: Permission) => boolean;
103
+ hasRole: (role: EnumUserRole) => boolean;
80
104
  hasUserLicence: (licenceType: EnumUserLicence) => boolean;
81
105
  hasVendorLicence: HasLicenceResult;
82
106
  isAdmin: boolean;
83
107
  isSuperAdmin: boolean;
84
108
  isLoading: boolean;
109
+ permissions: Permission[];
85
110
  getLicenseAccessLevel: (limitType: LimitType, resourceId: string, resourceType: EnumResourceType) => number;
86
111
  refetchUser: () => Promise<void>;
87
112
  setUser: (user: SafeUserType | null) => Promise<void>;
@@ -116,4 +141,4 @@ declare const UserProvider: React.FC<{
116
141
  }>;
117
142
  declare const useAuthUser: () => UseAuthReturnType;
118
143
 
119
- export { type AuthManager, type AuthManagerLike, type AuthStorageAdapter, DEFAULT_LIMITS, type HasLicenceResult, type LicencedResourceType, type LicencesByRole, type LimitType, type LogoutReason, type ProfileBadgeLicence, type RoleLicences, SUPER_ADMIN_EMAIL, type UseAuthCoreAdapters, type UseAuthReturnType, UserProvider, createAuthManager, getLicenceFlagsByRole, hasLicence, hasUserLicenceType, isLicencedResourceType, isProfileBadgeLicence, useAuthCore, useAuthUser };
144
+ export { type AuthManager, type AuthManagerLike, type AuthStorageAdapter, DEFAULT_LIMITS, type HasLicenceResult, type LicencedResourceType, type LicencesByRole, type LimitType, type LogoutReason, Permission, type ProfileBadgeLicence, ROLE_PERMISSIONS, type RoleLicences, SUPER_ADMIN_EMAIL, type UseAuthCoreAdapters, type UseAuthReturnType, UserProvider, createAuthManager, getLicenceFlagsByRole, getPermissionsForRoles, hasAllPermissions, hasAnyPermission, hasAnyRole, hasLicence, hasPermission, hasRole, hasUserLicenceType, isLicencedResourceType, isProfileBadgeLicence, permissionListIncludes, useAuthCore, useAuthUser };
@@ -1,4 +1,16 @@
1
1
  "use client";
2
+ import {
3
+ PERMISSIONS,
4
+ ROLE_PERMISSIONS,
5
+ WILDCARD_PERMISSION,
6
+ getPermissionsForRoles,
7
+ hasAllPermissions,
8
+ hasAnyPermission,
9
+ hasAnyRole,
10
+ hasPermission,
11
+ hasRole,
12
+ permissionListIncludes
13
+ } from "../chunk-GHW3ZGBY.mjs";
2
14
  import {
3
15
  USER_STORAGE_KEY
4
16
  } from "../chunk-DWO35OY4.mjs";
@@ -8,8 +20,8 @@ import {
8
20
  import {
9
21
  useGetUser,
10
22
  useLogout
11
- } from "../chunk-MIDSLTUJ.mjs";
12
- import "../chunk-D33VEY7Q.mjs";
23
+ } from "../chunk-UOFI3LKZ.mjs";
24
+ import "../chunk-VR3TDBJL.mjs";
13
25
 
14
26
  // src/auth/constants.ts
15
27
  var SUPER_ADMIN_EMAIL = "hello@cluemart.co.nz";
@@ -192,21 +204,35 @@ function useAuthCore(adapters) {
192
204
  (licenceType) => hasUserLicenceType(authUser, licenceType),
193
205
  [authUser]
194
206
  );
207
+ const permissions = useMemo(() => {
208
+ if (authUser?.permissions != null) {
209
+ return authUser.permissions;
210
+ }
211
+ return getPermissionsForRoles(authUser?.roles);
212
+ }, [authUser?.permissions, authUser?.roles]);
213
+ const hasPermissionFn = useCallback(
214
+ (permission) => permissionListIncludes(permissions, permission),
215
+ [permissions]
216
+ );
217
+ const hasRoleFn = useCallback(
218
+ (role) => hasRole(authUser?.roles, role),
219
+ [authUser?.roles]
220
+ );
195
221
  const isAdmin = useMemo(
196
- () => authUser?.role === "admin" /* ADMIN */,
197
- [authUser?.role]
222
+ () => hasRole(authUser?.roles, "admin" /* ADMIN */) || permissionListIncludes(permissions, "dashboard.admin") || permissionListIncludes(permissions, "*"),
223
+ [authUser?.roles, permissions]
198
224
  );
199
225
  const isSuperAdmin = useMemo(
200
- () => authUser?.role === "super_admin" /* SUPER_ADMIN */ && authUser?.email === SUPER_ADMIN_EMAIL,
201
- [authUser?.role, authUser?.email]
226
+ () => hasRole(authUser?.roles, "super_admin" /* SUPER_ADMIN */) && authUser?.email === SUPER_ADMIN_EMAIL,
227
+ [authUser?.roles, authUser?.email]
202
228
  );
203
229
  const isAffiliate = useMemo(
204
- () => authUser?.role === "affiliate" /* AFFILIATE */ && authUser?.affiliate !== null,
205
- [authUser?.role, authUser?.affiliate]
230
+ () => hasRole(authUser?.roles, "affiliate" /* AFFILIATE */) && authUser?.affiliate !== null && authUser?.affiliate !== void 0,
231
+ [authUser?.roles, authUser?.affiliate]
206
232
  );
207
233
  const isSchool = useMemo(
208
- () => authUser?.role === "school" /* SCHOOL */ && authUser?.school !== null,
209
- [authUser?.role, authUser?.school]
234
+ () => hasRole(authUser?.roles, "school" /* SCHOOL */) && authUser?.school !== null && authUser?.school !== void 0,
235
+ [authUser?.roles, authUser?.school]
210
236
  );
211
237
  useEffect(() => {
212
238
  const loadUser = async () => {
@@ -272,6 +298,8 @@ function useAuthCore(adapters) {
272
298
  handleLogoutExplicit,
273
299
  hasEventLicence,
274
300
  hasPartnerLicence,
301
+ hasPermission: hasPermissionFn,
302
+ hasRole: hasRoleFn,
275
303
  hasUserLicence,
276
304
  hasVendorLicence,
277
305
  isAdmin,
@@ -279,6 +307,7 @@ function useAuthCore(adapters) {
279
307
  isLoading: loading || isLoading,
280
308
  isSchool,
281
309
  isSuperAdmin,
310
+ permissions,
282
311
  refetchUser: handleRefetchUser,
283
312
  setUser: handleSetAuthUser
284
313
  };
@@ -300,14 +329,24 @@ var useAuthUser = () => {
300
329
  };
301
330
  export {
302
331
  DEFAULT_LIMITS,
332
+ PERMISSIONS,
333
+ ROLE_PERMISSIONS,
303
334
  SUPER_ADMIN_EMAIL,
304
335
  UserProvider,
336
+ WILDCARD_PERMISSION,
305
337
  createAuthManager,
306
338
  getLicenceFlagsByRole,
339
+ getPermissionsForRoles,
340
+ hasAllPermissions,
341
+ hasAnyPermission,
342
+ hasAnyRole,
307
343
  hasLicence,
344
+ hasPermission,
345
+ hasRole,
308
346
  hasUserLicenceType,
309
347
  isLicencedResourceType,
310
348
  isProfileBadgeLicence,
349
+ permissionListIncludes,
311
350
  useAuthCore,
312
351
  useAuthUser
313
352
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/auth/constants.ts","../../src/auth/createAuthManager.ts","../../src/auth/licenceUtils.ts","../../src/auth/useAuthCore.ts","../../src/auth/UserProvider.tsx"],"sourcesContent":["/** Super-admin identity used for elevated admin checks in clients. */\nexport const SUPER_ADMIN_EMAIL = \"hello@cluemart.co.nz\";\n","export type AuthManager = {\n logout: () => Promise<void>;\n setLogout: (fn: () => Promise<void>) => void;\n handleRefetchUser: () => Promise<void>;\n setUserRefetch: (fn: () => Promise<void>) => void;\n};\n\n/**\n * Creates an auth manager used by Apollo error links to trigger logout/refetch\n * without importing React. Matches the former mobile authManager shape.\n *\n * `logout()` dedupes concurrent calls via an in-flight promise so token-refresh\n * failures do not kick off multiple logout sequences.\n */\nexport function createAuthManager(): AuthManager {\n let logoutFn: (() => Promise<void>) | null = null;\n let userRefetchFn: (() => Promise<void>) | null = null;\n let logoutPromise: Promise<void> | null = null;\n\n return {\n handleRefetchUser: async () => {\n if (userRefetchFn) {\n await userRefetchFn();\n } else {\n console.warn(\"❌ User refetch function not set!\");\n }\n },\n logout(): Promise<void> {\n if (logoutPromise !== null) return logoutPromise;\n if (logoutFn === null) {\n console.warn(\"❌ Logout function not set!\");\n return Promise.resolve();\n }\n logoutPromise = logoutFn().finally(() => {\n logoutPromise = null;\n });\n return logoutPromise;\n },\n setLogout(fn: () => Promise<void>) {\n logoutFn = fn;\n },\n setUserRefetch(fn: () => Promise<void>) {\n userRefetchFn = fn;\n },\n };\n}\n","/* eslint-disable camelcase */\nimport { EnumResourceType, EnumUserLicence } from \"../enums\";\nimport type { SafeUserType } from \"../types\";\nimport { TIERS_BY_PRIORITY, type Tier } from \"../types/subscription\";\n\nimport type {\n HasLicenceResult,\n LicencedResourceType,\n LicencesByRole,\n LimitType,\n ProfileBadgeLicence,\n RoleLicences,\n} from \"./types\";\n\nexport function isLicencedResourceType(\n resourceType: EnumResourceType,\n): resourceType is LicencedResourceType {\n return (\n resourceType !== EnumResourceType.AFFILIATE &&\n resourceType !== EnumResourceType.SCHOOL\n );\n}\n\nexport function isProfileBadgeLicence(\n licenceType: EnumUserLicence,\n): licenceType is ProfileBadgeLicence {\n return (\n licenceType !== EnumUserLicence.STANDARD_AFFILIATE &&\n licenceType !== EnumUserLicence.STANDARD_SCHOOL\n );\n}\n\nexport const hasUserLicenceType = (\n authUser: SafeUserType | null,\n licenceType: EnumUserLicence,\n): boolean =>\n authUser?.licences?.some((licence) => licence.licenceType === licenceType) ??\n false;\n\nexport const hasLicence = (\n authUser: SafeUserType | null,\n licenceType: \"vendor\" | \"partner\" | \"event\",\n): HasLicenceResult => {\n const directLicence =\n authUser?.licences?.some((licence) =>\n licence.licenceType?.includes(licenceType),\n ) ?? false;\n\n const associateLicence =\n authUser?.associates?.some((associate) =>\n associate.licence?.licenceType?.includes(licenceType),\n ) ?? false;\n\n return {\n associateLicence,\n directLicence,\n };\n};\n\n/** Default limits per subscription tier. */\nexport const DEFAULT_LIMITS: Record<LimitType, Record<Tier, number>> = {\n // 1 means calendar/productMenu is enabled, 0 means disabled\n associates: { pro: 3, pro_plus: 3, standard: 0 },\n availability: { pro: 1, pro_plus: 1, standard: 0 },\n calendar: { pro: 1, pro_plus: 1, standard: 0 },\n images: { pro: 12, pro_plus: 12, standard: 6 },\n posters: { pro: 5, pro_plus: 5, standard: 5 },\n productsList: { pro: 1, pro_plus: 1, standard: 0 },\n relationShare: { pro: 1, pro_plus: 1, standard: 0 },\n statistics: { pro: 1, pro_plus: 1, standard: 0 },\n};\n\n/**\n * Parses an array of licence strings into structured, role-based licences.\n */\nexport function getLicenceFlagsByRole(licences?: string[]): LicencesByRole {\n const normalized = licences?.map((l) => l.toLowerCase()) ?? [];\n\n function resolve(role: EnumResourceType): RoleLicences {\n const result: RoleLicences = {\n pro_plus: false,\n // eslint-disable-next-line sort-keys\n pro: false,\n standard: false,\n };\n\n for (const tier of TIERS_BY_PRIORITY) {\n if (normalized.some((l) => l.startsWith(`${tier}_${role}`))) {\n result[tier] = true;\n break; // stop at first match → ensures mutual exclusivity\n }\n }\n\n return result;\n }\n\n return {\n event: resolve(EnumResourceType.EVENT),\n partner: resolve(EnumResourceType.PARTNER),\n vendor: resolve(EnumResourceType.VENDOR),\n };\n}\n","/* eslint-disable camelcase */\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport { EnumResourceType, EnumUserLicence, EnumUserRole } from \"../enums\";\nimport { useLogout } from \"../graphql/hooks/auth\";\nimport { useGetUser } from \"../graphql/hooks/user/hooksQuery\";\nimport { USER_STORAGE_KEY } from \"../storage\";\nimport type { SafeUserType } from \"../types\";\n\nimport { SUPER_ADMIN_EMAIL } from \"./constants\";\nimport {\n DEFAULT_LIMITS,\n getLicenceFlagsByRole,\n hasLicence,\n hasUserLicenceType,\n isLicencedResourceType,\n} from \"./licenceUtils\";\nimport type {\n LimitType,\n LogoutReason,\n UseAuthCoreAdapters,\n UseAuthReturnType,\n} from \"./types\";\n\n/**\n * Platform-agnostic auth session core (source of truth for shared useAuth).\n *\n * Owns: persisted user load/set, refetch, role/licence flags, logout orchestration.\n * Does not own: AsyncStorage vs localStorage, Expo/Next navigation, toasts,\n * Apollo/WS reset, Firebase — those stay in each app's adapter wrapper.\n */\nexport function useAuthCore(adapters: UseAuthCoreAdapters): UseAuthReturnType {\n const {\n storage,\n authManager,\n afterLogout,\n shouldCallLogoutMutation = () => true,\n notifyLogoutSuccess,\n notifySessionExpired,\n onError,\n } = adapters;\n\n const [authUser, setAuthUser] = useState<SafeUserType | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n\n const userId = useMemo(() => authUser?._id ?? \"\", [authUser?._id]);\n const { refetch } = useGetUser(userId);\n const { logout, loading } = useLogout();\n\n const handleSetAuthUser = useCallback(\n async (user: SafeUserType | null) => {\n setAuthUser(user);\n if (user) {\n await storage.setItem(USER_STORAGE_KEY, JSON.stringify(user));\n } else {\n await storage.removeItem(USER_STORAGE_KEY);\n }\n },\n [storage],\n );\n\n const handleRefetchUser = useCallback(async () => {\n if (!authUser) return;\n try {\n const result = await refetch();\n if (!result) return;\n const { data } = result;\n if (data?.user) await handleSetAuthUser(data.user);\n } catch (error: unknown) {\n onError?.(error, { action: \"refetchUser\" });\n console.warn(\n \"Failed to refetch user:\",\n error instanceof Error ? error.message : error,\n );\n }\n }, [authUser, handleSetAuthUser, onError, refetch]);\n\n const licences = useCallback(\n (resourceId: string) => {\n const myLicences =\n authUser?.licences?.map((licence) => licence.licenceType) ?? [];\n const associateLicences =\n authUser?.associates?.map(\n (associate) => associate.licence.licenceType,\n ) ?? [];\n\n // No resource yet (e.g. create flow / unloaded id): use the user's own\n // licences only — never hard-code elevated tiers for an empty id.\n if (resourceId === \"\") {\n return getLicenceFlagsByRole(myLicences);\n }\n\n const myResourceIds = [\n authUser?.vendor ?? null,\n authUser?.partner ?? null,\n ...(authUser?.events ?? []),\n ].filter((id): id is string => id !== null);\n\n return myResourceIds.includes(resourceId)\n ? getLicenceFlagsByRole(myLicences)\n : getLicenceFlagsByRole(associateLicences);\n },\n [authUser],\n );\n\n const getLicenseAccessLevel = useCallback(\n (\n limitType: LimitType,\n resourceId: string,\n resourceType: EnumResourceType,\n ): number => {\n if (!isLicencedResourceType(resourceType)) {\n return 0;\n }\n\n const roleLicences = licences(resourceId)[resourceType];\n\n if (roleLicences.pro_plus) return DEFAULT_LIMITS[limitType].pro_plus;\n if (roleLicences.pro) return DEFAULT_LIMITS[limitType].pro;\n if (roleLicences.standard) return DEFAULT_LIMITS[limitType].standard;\n\n return 0;\n },\n [licences],\n );\n\n const hasVendorLicence = useMemo(\n () => hasLicence(authUser, \"vendor\"),\n [authUser],\n );\n\n const hasPartnerLicence = useMemo(\n () => hasLicence(authUser, \"partner\"),\n [authUser],\n );\n\n const hasEventLicence = useMemo(\n () => hasLicence(authUser, \"event\"),\n [authUser],\n );\n\n const hasUserLicence = useCallback(\n (licenceType: EnumUserLicence) => hasUserLicenceType(authUser, licenceType),\n [authUser],\n );\n\n const isAdmin = useMemo(\n () => authUser?.role === EnumUserRole.ADMIN,\n [authUser?.role],\n );\n\n const isSuperAdmin = useMemo(\n () =>\n authUser?.role === EnumUserRole.SUPER_ADMIN &&\n authUser?.email === SUPER_ADMIN_EMAIL,\n [authUser?.role, authUser?.email],\n );\n\n const isAffiliate = useMemo(\n () =>\n authUser?.role === EnumUserRole.AFFILIATE && authUser?.affiliate !== null,\n [authUser?.role, authUser?.affiliate],\n );\n\n const isSchool = useMemo(\n () => authUser?.role === EnumUserRole.SCHOOL && authUser?.school !== null,\n [authUser?.role, authUser?.school],\n );\n\n // Mount-only hydrate from storage. Do not re-run when adapter identities\n // change — that can overwrite a newer in-memory user (e.g. post-login setUser).\n useEffect(() => {\n const loadUser = async () => {\n try {\n const userJson = await storage.getItem(USER_STORAGE_KEY);\n await handleSetAuthUser(userJson ? JSON.parse(userJson) : null);\n } catch (error: unknown) {\n onError?.(error, { action: \"loadUserFromStorage\" });\n console.error(\"Failed to load user from storage:\", error);\n } finally {\n setIsLoading(false);\n }\n };\n\n void loadUser();\n }, []);\n\n const logoutWithReason = useCallback(\n async (reason: LogoutReason) => {\n try {\n if (shouldCallLogoutMutation(reason)) {\n try {\n const result = await logout();\n const message = result?.data?.logout?.message as string | undefined;\n if (message) {\n notifyLogoutSuccess?.(message);\n }\n } catch (err: unknown) {\n onError?.(err, { action: \"logout\" });\n console.warn(\"Logout request failed (ignored):\", err);\n }\n }\n } finally {\n await afterLogout(reason);\n setAuthUser(null);\n await storage.removeItem(USER_STORAGE_KEY);\n }\n },\n [\n afterLogout,\n logout,\n notifyLogoutSuccess,\n onError,\n shouldCallLogoutMutation,\n storage,\n ],\n );\n\n const handleLogoutExplicit = useCallback(\n () => logoutWithReason(\"manual\"),\n [logoutWithReason],\n );\n\n const handleLogoutExpired = useCallback(async () => {\n const hadSession = authUser != null;\n if (!hadSession) return;\n await logoutWithReason(\"expired\");\n notifySessionExpired?.();\n }, [authUser, logoutWithReason, notifySessionExpired]);\n\n useEffect(() => {\n authManager.setLogout(() => handleLogoutExpired());\n authManager.setUserRefetch(() => handleRefetchUser());\n }, [authManager, handleLogoutExpired, handleRefetchUser]);\n\n return {\n authUser,\n getLicenseAccessLevel,\n handleLogoutExplicit,\n hasEventLicence,\n hasPartnerLicence,\n hasUserLicence,\n hasVendorLicence,\n isAdmin,\n isAffiliate,\n isLoading: loading || isLoading,\n isSchool,\n isSuperAdmin,\n refetchUser: handleRefetchUser,\n setUser: handleSetAuthUser,\n };\n}\n","/**\n * Shared React context for auth session state.\n *\n * Apps keep a thin local UserProvider that calls their platform `useAuth`\n * (adapters) and pass the result here as `value`. Import `useAuthUser` from\n * this module (or re-export it) so consumers share one context instance.\n *\n * `\"use client\"`: required for Next.js; ignored by React Native.\n */\n\"use client\";\n\nimport React, { createContext, useContext, type ReactNode } from \"react\";\n\nimport type { UseAuthReturnType } from \"./types\";\n\nconst UserContext = createContext<UseAuthReturnType | undefined>(undefined);\n\n/**\n * Provides auth session value from the app's thin useAuth wrapper.\n */\nexport const UserProvider: React.FC<{\n children: ReactNode;\n value: UseAuthReturnType;\n}> = ({ children, value }) => {\n return <UserContext.Provider value={value}>{children}</UserContext.Provider>;\n};\n\nexport const useAuthUser = (): UseAuthReturnType => {\n const context = useContext(UserContext);\n if (!context) {\n throw new Error(\"useAuthUser must be used within a UserProvider\");\n }\n return context;\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/auth/constants.ts","../../src/auth/createAuthManager.ts","../../src/auth/licenceUtils.ts","../../src/auth/useAuthCore.ts","../../src/auth/UserProvider.tsx"],"sourcesContent":["/** Super-admin identity used for elevated admin checks in clients. */\nexport const SUPER_ADMIN_EMAIL = \"hello@cluemart.co.nz\";\n","export type AuthManager = {\n logout: () => Promise<void>;\n setLogout: (fn: () => Promise<void>) => void;\n handleRefetchUser: () => Promise<void>;\n setUserRefetch: (fn: () => Promise<void>) => void;\n};\n\n/**\n * Creates an auth manager used by Apollo error links to trigger logout/refetch\n * without importing React. Matches the former mobile authManager shape.\n *\n * `logout()` dedupes concurrent calls via an in-flight promise so token-refresh\n * failures do not kick off multiple logout sequences.\n */\nexport function createAuthManager(): AuthManager {\n let logoutFn: (() => Promise<void>) | null = null;\n let userRefetchFn: (() => Promise<void>) | null = null;\n let logoutPromise: Promise<void> | null = null;\n\n return {\n handleRefetchUser: async () => {\n if (userRefetchFn) {\n await userRefetchFn();\n } else {\n console.warn(\"❌ User refetch function not set!\");\n }\n },\n logout(): Promise<void> {\n if (logoutPromise !== null) return logoutPromise;\n if (logoutFn === null) {\n console.warn(\"❌ Logout function not set!\");\n return Promise.resolve();\n }\n logoutPromise = logoutFn().finally(() => {\n logoutPromise = null;\n });\n return logoutPromise;\n },\n setLogout(fn: () => Promise<void>) {\n logoutFn = fn;\n },\n setUserRefetch(fn: () => Promise<void>) {\n userRefetchFn = fn;\n },\n };\n}\n","/* eslint-disable camelcase */\nimport { EnumResourceType, EnumUserLicence } from \"../enums\";\nimport type { SafeUserType } from \"../types\";\nimport { TIERS_BY_PRIORITY, type Tier } from \"../types/subscription\";\n\nimport type {\n HasLicenceResult,\n LicencedResourceType,\n LicencesByRole,\n LimitType,\n ProfileBadgeLicence,\n RoleLicences,\n} from \"./types\";\n\nexport function isLicencedResourceType(\n resourceType: EnumResourceType,\n): resourceType is LicencedResourceType {\n return (\n resourceType !== EnumResourceType.AFFILIATE &&\n resourceType !== EnumResourceType.SCHOOL\n );\n}\n\nexport function isProfileBadgeLicence(\n licenceType: EnumUserLicence,\n): licenceType is ProfileBadgeLicence {\n return (\n licenceType !== EnumUserLicence.STANDARD_AFFILIATE &&\n licenceType !== EnumUserLicence.STANDARD_SCHOOL\n );\n}\n\nexport const hasUserLicenceType = (\n authUser: SafeUserType | null,\n licenceType: EnumUserLicence,\n): boolean =>\n authUser?.licences?.some((licence) => licence.licenceType === licenceType) ??\n false;\n\nexport const hasLicence = (\n authUser: SafeUserType | null,\n licenceType: \"vendor\" | \"partner\" | \"event\",\n): HasLicenceResult => {\n const directLicence =\n authUser?.licences?.some((licence) =>\n licence.licenceType?.includes(licenceType),\n ) ?? false;\n\n const associateLicence =\n authUser?.associates?.some((associate) =>\n associate.licence?.licenceType?.includes(licenceType),\n ) ?? false;\n\n return {\n associateLicence,\n directLicence,\n };\n};\n\n/** Default limits per subscription tier. */\nexport const DEFAULT_LIMITS: Record<LimitType, Record<Tier, number>> = {\n // 1 means calendar/productMenu is enabled, 0 means disabled\n associates: { pro: 3, pro_plus: 3, standard: 0 },\n availability: { pro: 1, pro_plus: 1, standard: 0 },\n calendar: { pro: 1, pro_plus: 1, standard: 0 },\n images: { pro: 12, pro_plus: 12, standard: 6 },\n posters: { pro: 5, pro_plus: 5, standard: 5 },\n productsList: { pro: 1, pro_plus: 1, standard: 0 },\n relationShare: { pro: 1, pro_plus: 1, standard: 0 },\n statistics: { pro: 1, pro_plus: 1, standard: 0 },\n};\n\n/**\n * Parses an array of licence strings into structured, role-based licences.\n */\nexport function getLicenceFlagsByRole(licences?: string[]): LicencesByRole {\n const normalized = licences?.map((l) => l.toLowerCase()) ?? [];\n\n function resolve(role: EnumResourceType): RoleLicences {\n const result: RoleLicences = {\n pro_plus: false,\n // eslint-disable-next-line sort-keys\n pro: false,\n standard: false,\n };\n\n for (const tier of TIERS_BY_PRIORITY) {\n if (normalized.some((l) => l.startsWith(`${tier}_${role}`))) {\n result[tier] = true;\n break; // stop at first match → ensures mutual exclusivity\n }\n }\n\n return result;\n }\n\n return {\n event: resolve(EnumResourceType.EVENT),\n partner: resolve(EnumResourceType.PARTNER),\n vendor: resolve(EnumResourceType.VENDOR),\n };\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport { EnumResourceType, EnumUserLicence, EnumUserRole } from \"../enums\";\nimport { useLogout } from \"../graphql/hooks/auth\";\nimport { useGetUser } from \"../graphql/hooks/user/hooksQuery\";\nimport { USER_STORAGE_KEY } from \"../storage\";\nimport type { SafeUserType } from \"../types\";\n\nimport { SUPER_ADMIN_EMAIL } from \"./constants\";\nimport {\n DEFAULT_LIMITS,\n getLicenceFlagsByRole,\n hasLicence,\n hasUserLicenceType,\n isLicencedResourceType,\n} from \"./licenceUtils\";\nimport {\n getPermissionsForRoles,\n hasRole as roleHasRole,\n permissionListIncludes,\n} from \"./permissions\";\nimport type { Permission } from \"./permissions\";\nimport type {\n LimitType,\n LogoutReason,\n UseAuthCoreAdapters,\n UseAuthReturnType,\n} from \"./types\";\n\n/**\n * Platform-agnostic auth session core (source of truth for shared useAuth).\n *\n * Owns: persisted user load/set, refetch, role/licence flags, logout orchestration.\n * Does not own: AsyncStorage vs localStorage, Expo/Next navigation, toasts,\n * Apollo/WS reset, Firebase — those stay in each app's adapter wrapper.\n */\nexport function useAuthCore(adapters: UseAuthCoreAdapters): UseAuthReturnType {\n const {\n storage,\n authManager,\n afterLogout,\n shouldCallLogoutMutation = () => true,\n notifyLogoutSuccess,\n notifySessionExpired,\n onError,\n } = adapters;\n\n const [authUser, setAuthUser] = useState<SafeUserType | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n\n const userId = useMemo(() => authUser?._id ?? \"\", [authUser?._id]);\n const { refetch } = useGetUser(userId);\n const { logout, loading } = useLogout();\n\n const handleSetAuthUser = useCallback(\n async (user: SafeUserType | null) => {\n setAuthUser(user);\n if (user) {\n await storage.setItem(USER_STORAGE_KEY, JSON.stringify(user));\n } else {\n await storage.removeItem(USER_STORAGE_KEY);\n }\n },\n [storage],\n );\n\n const handleRefetchUser = useCallback(async () => {\n if (!authUser) return;\n try {\n const result = await refetch();\n if (!result) return;\n const { data } = result;\n if (data?.user) await handleSetAuthUser(data.user);\n } catch (error: unknown) {\n onError?.(error, { action: \"refetchUser\" });\n console.warn(\n \"Failed to refetch user:\",\n error instanceof Error ? error.message : error,\n );\n }\n }, [authUser, handleSetAuthUser, onError, refetch]);\n\n const licences = useCallback(\n (resourceId: string) => {\n const myLicences =\n authUser?.licences?.map((licence) => licence.licenceType) ?? [];\n const associateLicences =\n authUser?.associates?.map(\n (associate) => associate.licence.licenceType,\n ) ?? [];\n\n // No resource yet (e.g. create flow / unloaded id): use the user's own\n // licences only — never hard-code elevated tiers for an empty id.\n if (resourceId === \"\") {\n return getLicenceFlagsByRole(myLicences);\n }\n\n const myResourceIds = [\n authUser?.vendor ?? null,\n authUser?.partner ?? null,\n ...(authUser?.events ?? []),\n ].filter((id): id is string => id !== null);\n\n return myResourceIds.includes(resourceId)\n ? getLicenceFlagsByRole(myLicences)\n : getLicenceFlagsByRole(associateLicences);\n },\n [authUser],\n );\n\n const getLicenseAccessLevel = useCallback(\n (\n limitType: LimitType,\n resourceId: string,\n resourceType: EnumResourceType,\n ): number => {\n if (!isLicencedResourceType(resourceType)) {\n return 0;\n }\n\n const roleLicences = licences(resourceId)[resourceType];\n\n if (roleLicences.pro_plus) return DEFAULT_LIMITS[limitType].pro_plus;\n if (roleLicences.pro) return DEFAULT_LIMITS[limitType].pro;\n if (roleLicences.standard) return DEFAULT_LIMITS[limitType].standard;\n\n return 0;\n },\n [licences],\n );\n\n const hasVendorLicence = useMemo(\n () => hasLicence(authUser, \"vendor\"),\n [authUser],\n );\n\n const hasPartnerLicence = useMemo(\n () => hasLicence(authUser, \"partner\"),\n [authUser],\n );\n\n const hasEventLicence = useMemo(\n () => hasLicence(authUser, \"event\"),\n [authUser],\n );\n\n const hasUserLicence = useCallback(\n (licenceType: EnumUserLicence) => hasUserLicenceType(authUser, licenceType),\n [authUser],\n );\n\n const permissions = useMemo(() => {\n if (authUser?.permissions != null) {\n return authUser.permissions;\n }\n return getPermissionsForRoles(authUser?.roles);\n }, [authUser?.permissions, authUser?.roles]);\n\n const hasPermissionFn = useCallback(\n (permission: Permission) => permissionListIncludes(permissions, permission),\n [permissions],\n );\n\n const hasRoleFn = useCallback(\n (role: EnumUserRole) => roleHasRole(authUser?.roles, role),\n [authUser?.roles],\n );\n\n const isAdmin = useMemo(\n () =>\n roleHasRole(authUser?.roles, EnumUserRole.ADMIN) ||\n permissionListIncludes(permissions, \"dashboard.admin\") ||\n permissionListIncludes(permissions, \"*\"),\n [authUser?.roles, permissions],\n );\n\n const isSuperAdmin = useMemo(\n () =>\n roleHasRole(authUser?.roles, EnumUserRole.SUPER_ADMIN) &&\n authUser?.email === SUPER_ADMIN_EMAIL,\n [authUser?.roles, authUser?.email],\n );\n\n const isAffiliate = useMemo(\n () =>\n roleHasRole(authUser?.roles, EnumUserRole.AFFILIATE) &&\n authUser?.affiliate !== null &&\n authUser?.affiliate !== undefined,\n [authUser?.roles, authUser?.affiliate],\n );\n\n const isSchool = useMemo(\n () =>\n roleHasRole(authUser?.roles, EnumUserRole.SCHOOL) &&\n authUser?.school !== null &&\n authUser?.school !== undefined,\n [authUser?.roles, authUser?.school],\n );\n\n // Mount-only hydrate from storage. Do not re-run when adapter identities\n // change — that can overwrite a newer in-memory user (e.g. post-login setUser).\n useEffect(() => {\n const loadUser = async () => {\n try {\n const userJson = await storage.getItem(USER_STORAGE_KEY);\n await handleSetAuthUser(userJson ? JSON.parse(userJson) : null);\n } catch (error: unknown) {\n onError?.(error, { action: \"loadUserFromStorage\" });\n console.error(\"Failed to load user from storage:\", error);\n } finally {\n setIsLoading(false);\n }\n };\n\n void loadUser();\n }, []);\n\n const logoutWithReason = useCallback(\n async (reason: LogoutReason) => {\n try {\n if (shouldCallLogoutMutation(reason)) {\n try {\n const result = await logout();\n const message = result?.data?.logout?.message as string | undefined;\n if (message) {\n notifyLogoutSuccess?.(message);\n }\n } catch (err: unknown) {\n onError?.(err, { action: \"logout\" });\n console.warn(\"Logout request failed (ignored):\", err);\n }\n }\n } finally {\n await afterLogout(reason);\n setAuthUser(null);\n await storage.removeItem(USER_STORAGE_KEY);\n }\n },\n [\n afterLogout,\n logout,\n notifyLogoutSuccess,\n onError,\n shouldCallLogoutMutation,\n storage,\n ],\n );\n\n const handleLogoutExplicit = useCallback(\n () => logoutWithReason(\"manual\"),\n [logoutWithReason],\n );\n\n const handleLogoutExpired = useCallback(async () => {\n const hadSession = authUser != null;\n if (!hadSession) return;\n await logoutWithReason(\"expired\");\n notifySessionExpired?.();\n }, [authUser, logoutWithReason, notifySessionExpired]);\n\n useEffect(() => {\n authManager.setLogout(() => handleLogoutExpired());\n authManager.setUserRefetch(() => handleRefetchUser());\n }, [authManager, handleLogoutExpired, handleRefetchUser]);\n\n return {\n authUser,\n getLicenseAccessLevel,\n handleLogoutExplicit,\n hasEventLicence,\n hasPartnerLicence,\n hasPermission: hasPermissionFn,\n hasRole: hasRoleFn,\n hasUserLicence,\n hasVendorLicence,\n isAdmin,\n isAffiliate,\n isLoading: loading || isLoading,\n isSchool,\n isSuperAdmin,\n permissions,\n refetchUser: handleRefetchUser,\n setUser: handleSetAuthUser,\n };\n}\n","/**\n * Shared React context for auth session state.\n *\n * Apps keep a thin local UserProvider that calls their platform `useAuth`\n * (adapters) and pass the result here as `value`. Import `useAuthUser` from\n * this module (or re-export it) so consumers share one context instance.\n *\n * `\"use client\"`: required for Next.js; ignored by React Native.\n */\n\"use client\";\n\nimport React, { createContext, useContext, type ReactNode } from \"react\";\n\nimport type { UseAuthReturnType } from \"./types\";\n\nconst UserContext = createContext<UseAuthReturnType | undefined>(undefined);\n\n/**\n * Provides auth session value from the app's thin useAuth wrapper.\n */\nexport const UserProvider: React.FC<{\n children: ReactNode;\n value: UseAuthReturnType;\n}> = ({ children, value }) => {\n return <UserContext.Provider value={value}>{children}</UserContext.Provider>;\n};\n\nexport const useAuthUser = (): UseAuthReturnType => {\n const context = useContext(UserContext);\n if (!context) {\n throw new Error(\"useAuthUser must be used within a UserProvider\");\n }\n return context;\n};\n"],"mappings":"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","names":[]}
@@ -6,7 +6,7 @@ import {
6
6
  nzStartOfDay,
7
7
  sortDatesChronologically,
8
8
  stripOverlaySubtitleSpecialChars
9
- } from "./chunk-UHDYJBIX.mjs";
9
+ } from "./chunk-VNF22ITY.mjs";
10
10
  import {
11
11
  PROMO_CODE_PREFIX,
12
12
  gameScreenIdentifierList
@@ -18,7 +18,7 @@ import {
18
18
  EnumInviteStatus,
19
19
  EnumPaymentMethod,
20
20
  EnumRegions
21
- } from "./chunk-D33VEY7Q.mjs";
21
+ } from "./chunk-VR3TDBJL.mjs";
22
22
 
23
23
  // src/utils/dailyClueGame.ts
24
24
  function createSeededRng(seed) {
@@ -1658,4 +1658,4 @@ export {
1658
1658
  toUserFacingErrorMessage,
1659
1659
  getErrorMessage
1660
1660
  };
1661
- //# sourceMappingURL=chunk-N7KENXCS.mjs.map
1661
+ //# sourceMappingURL=chunk-4NGXTQWT.mjs.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  mapArrayToOptions
3
- } from "./chunk-UHDYJBIX.mjs";
3
+ } from "./chunk-VNF22ITY.mjs";
4
4
  import {
5
5
  EnumFoodFlavor
6
- } from "./chunk-D33VEY7Q.mjs";
6
+ } from "./chunk-VR3TDBJL.mjs";
7
7
 
8
8
  // src/formFields/vendor/vendor.ts
9
9
  var vendorBasicInfoFields = [
@@ -959,4 +959,4 @@ export {
959
959
  contactUsFields,
960
960
  partnerBasicInfoFields
961
961
  };
962
- //# sourceMappingURL=chunk-IREUJYMR.mjs.map
962
+ //# sourceMappingURL=chunk-AQR53ECY.mjs.map
@@ -0,0 +1,168 @@
1
+ // src/auth/permissions/permissions.ts
2
+ var PERMISSIONS = [
3
+ "*",
4
+ // Dashboards
5
+ "dashboard.admin",
6
+ "dashboard.affiliate",
7
+ "dashboard.customer",
8
+ "dashboard.event",
9
+ "dashboard.partner",
10
+ "dashboard.school",
11
+ "dashboard.vendor",
12
+ // Admin: users
13
+ "users.delete",
14
+ "users.read",
15
+ "users.update",
16
+ // Admin: events
17
+ "events.create",
18
+ "events.delete",
19
+ "events.read",
20
+ "events.update",
21
+ // Admin: vendors
22
+ "vendors.create",
23
+ "vendors.delete",
24
+ "vendors.read",
25
+ "vendors.update",
26
+ // Admin: partners
27
+ "partners.create",
28
+ "partners.delete",
29
+ "partners.read",
30
+ "partners.update",
31
+ // Admin: schools
32
+ "schools.create",
33
+ "schools.delete",
34
+ "schools.read",
35
+ "schools.update",
36
+ // Admin: affiliates
37
+ "affiliates.create",
38
+ "affiliates.delete",
39
+ "affiliates.read",
40
+ "affiliates.update",
41
+ // Admin: ads / posts / settings
42
+ "ads.create",
43
+ "ads.delete",
44
+ "ads.read",
45
+ "ads.update",
46
+ "posts.create",
47
+ "posts.delete",
48
+ "posts.read",
49
+ "posts.update",
50
+ "settings.read",
51
+ "settings.update",
52
+ // Product: own-resource management
53
+ "affiliates.manage_own",
54
+ "events.manage_own",
55
+ "partners.manage_own",
56
+ "schools.manage_own",
57
+ "vendors.manage_own"
58
+ ];
59
+ var WILDCARD_PERMISSION = "*";
60
+
61
+ // src/auth/permissions/rolePermissions.ts
62
+ var ADMIN_PERMISSIONS = [
63
+ "dashboard.admin",
64
+ "users.read",
65
+ "users.update",
66
+ "users.delete",
67
+ "events.read",
68
+ "events.create",
69
+ "events.update",
70
+ "events.delete",
71
+ "vendors.read",
72
+ "vendors.create",
73
+ "vendors.update",
74
+ "vendors.delete",
75
+ "partners.read",
76
+ "partners.create",
77
+ "partners.update",
78
+ "partners.delete",
79
+ "schools.read",
80
+ "schools.create",
81
+ "schools.update",
82
+ "schools.delete",
83
+ "affiliates.read",
84
+ "affiliates.create",
85
+ "affiliates.update",
86
+ "affiliates.delete",
87
+ "ads.read",
88
+ "ads.create",
89
+ "ads.update",
90
+ "ads.delete",
91
+ "posts.read",
92
+ "posts.create",
93
+ "posts.update",
94
+ "posts.delete",
95
+ "settings.read",
96
+ "settings.update"
97
+ ];
98
+ var ROLE_PERMISSIONS = {
99
+ ["super_admin" /* SUPER_ADMIN */]: ["*"],
100
+ ["admin" /* ADMIN */]: ADMIN_PERMISSIONS,
101
+ ["customer" /* CUSTOMER */]: ["dashboard.customer"],
102
+ ["event" /* EVENT */]: ["dashboard.event", "events.manage_own"],
103
+ ["vendor" /* VENDOR */]: ["dashboard.vendor", "vendors.manage_own"],
104
+ ["partner" /* PARTNER */]: ["dashboard.partner", "partners.manage_own"],
105
+ ["school" /* SCHOOL */]: ["dashboard.school", "schools.manage_own"],
106
+ ["affiliate" /* AFFILIATE */]: ["dashboard.affiliate", "affiliates.manage_own"]
107
+ };
108
+
109
+ // src/auth/permissions/helpers.ts
110
+ function normalizeRoles(roles) {
111
+ if (!roles?.length) return [];
112
+ return roles;
113
+ }
114
+ function getPermissionsForRoles(roles) {
115
+ const seen = /* @__PURE__ */ new Set();
116
+ const result = [];
117
+ for (const role of normalizeRoles(roles)) {
118
+ const perms = ROLE_PERMISSIONS[role] ?? [];
119
+ for (const perm of perms) {
120
+ if (!seen.has(perm)) {
121
+ seen.add(perm);
122
+ result.push(perm);
123
+ }
124
+ }
125
+ }
126
+ return result;
127
+ }
128
+ function permissionListIncludes(permissions, permission) {
129
+ if (!permissions?.length) return false;
130
+ const set = new Set(permissions);
131
+ if (set.has(WILDCARD_PERMISSION)) return true;
132
+ return set.has(permission);
133
+ }
134
+ function hasPermission(roles, permission) {
135
+ return permissionListIncludes(getPermissionsForRoles(roles), permission);
136
+ }
137
+ function hasAnyPermission(roles, permissions) {
138
+ if (permissions.length === 0) return false;
139
+ const granted = getPermissionsForRoles(roles);
140
+ return permissions.some((p) => permissionListIncludes(granted, p));
141
+ }
142
+ function hasAllPermissions(roles, permissions) {
143
+ if (permissions.length === 0) return true;
144
+ const granted = getPermissionsForRoles(roles);
145
+ return permissions.every((p) => permissionListIncludes(granted, p));
146
+ }
147
+ function hasRole(roles, role) {
148
+ return normalizeRoles(roles).includes(role);
149
+ }
150
+ function hasAnyRole(roles, checkRoles) {
151
+ if (checkRoles.length === 0) return false;
152
+ const set = new Set(normalizeRoles(roles));
153
+ return checkRoles.some((r) => set.has(r));
154
+ }
155
+
156
+ export {
157
+ PERMISSIONS,
158
+ WILDCARD_PERMISSION,
159
+ ROLE_PERMISSIONS,
160
+ getPermissionsForRoles,
161
+ permissionListIncludes,
162
+ hasPermission,
163
+ hasAnyPermission,
164
+ hasAllPermissions,
165
+ hasRole,
166
+ hasAnyRole
167
+ };
168
+ //# sourceMappingURL=chunk-GHW3ZGBY.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/auth/permissions/permissions.ts","../src/auth/permissions/rolePermissions.ts","../src/auth/permissions/helpers.ts"],"sourcesContent":["/**\n * Canonical permission IDs. Add new permissions here first, then map them in\n * ROLE_PERMISSIONS. Prefer resource.action names (e.g. users.read).\n */\nexport const PERMISSIONS = [\n \"*\",\n // Dashboards\n \"dashboard.admin\",\n \"dashboard.affiliate\",\n \"dashboard.customer\",\n \"dashboard.event\",\n \"dashboard.partner\",\n \"dashboard.school\",\n \"dashboard.vendor\",\n // Admin: users\n \"users.delete\",\n \"users.read\",\n \"users.update\",\n // Admin: events\n \"events.create\",\n \"events.delete\",\n \"events.read\",\n \"events.update\",\n // Admin: vendors\n \"vendors.create\",\n \"vendors.delete\",\n \"vendors.read\",\n \"vendors.update\",\n // Admin: partners\n \"partners.create\",\n \"partners.delete\",\n \"partners.read\",\n \"partners.update\",\n // Admin: schools\n \"schools.create\",\n \"schools.delete\",\n \"schools.read\",\n \"schools.update\",\n // Admin: affiliates\n \"affiliates.create\",\n \"affiliates.delete\",\n \"affiliates.read\",\n \"affiliates.update\",\n // Admin: ads / posts / settings\n \"ads.create\",\n \"ads.delete\",\n \"ads.read\",\n \"ads.update\",\n \"posts.create\",\n \"posts.delete\",\n \"posts.read\",\n \"posts.update\",\n \"settings.read\",\n \"settings.update\",\n // Product: own-resource management\n \"affiliates.manage_own\",\n \"events.manage_own\",\n \"partners.manage_own\",\n \"schools.manage_own\",\n \"vendors.manage_own\",\n] as const;\n\nexport type Permission = (typeof PERMISSIONS)[number];\n\nexport const WILDCARD_PERMISSION: Permission = \"*\";\n","import { EnumUserRole } from \"../../enums\";\n\nimport type { Permission } from \"./permissions\";\n\nconst ADMIN_PERMISSIONS: readonly Permission[] = [\n \"dashboard.admin\",\n \"users.read\",\n \"users.update\",\n \"users.delete\",\n \"events.read\",\n \"events.create\",\n \"events.update\",\n \"events.delete\",\n \"vendors.read\",\n \"vendors.create\",\n \"vendors.update\",\n \"vendors.delete\",\n \"partners.read\",\n \"partners.create\",\n \"partners.update\",\n \"partners.delete\",\n \"schools.read\",\n \"schools.create\",\n \"schools.update\",\n \"schools.delete\",\n \"affiliates.read\",\n \"affiliates.create\",\n \"affiliates.update\",\n \"affiliates.delete\",\n \"ads.read\",\n \"ads.create\",\n \"ads.update\",\n \"ads.delete\",\n \"posts.read\",\n \"posts.create\",\n \"posts.update\",\n \"posts.delete\",\n \"settings.read\",\n \"settings.update\",\n];\n\n/**\n * Static role → permissions map. Source of truth for access.\n * Permissions for a user = union of all their roles' lists.\n */\nexport const ROLE_PERMISSIONS: Record<EnumUserRole, readonly Permission[]> = {\n [EnumUserRole.SUPER_ADMIN]: [\"*\"],\n [EnumUserRole.ADMIN]: ADMIN_PERMISSIONS,\n [EnumUserRole.CUSTOMER]: [\"dashboard.customer\"],\n [EnumUserRole.EVENT]: [\"dashboard.event\", \"events.manage_own\"],\n [EnumUserRole.VENDOR]: [\"dashboard.vendor\", \"vendors.manage_own\"],\n [EnumUserRole.PARTNER]: [\"dashboard.partner\", \"partners.manage_own\"],\n [EnumUserRole.SCHOOL]: [\"dashboard.school\", \"schools.manage_own\"],\n [EnumUserRole.AFFILIATE]: [\"dashboard.affiliate\", \"affiliates.manage_own\"],\n};\n","import { EnumUserRole } from \"../../enums\";\n\nimport type { Permission } from \"./permissions\";\nimport { WILDCARD_PERMISSION } from \"./permissions\";\nimport { ROLE_PERMISSIONS } from \"./rolePermissions\";\n\nfunction normalizeRoles(\n roles: EnumUserRole[] | null | undefined,\n): EnumUserRole[] {\n if (!roles?.length) return [];\n return roles;\n}\n\n/**\n * Union of permissions for the given roles (deduped, stable order).\n */\nexport function getPermissionsForRoles(\n roles: EnumUserRole[] | null | undefined,\n): Permission[] {\n const seen = new Set<Permission>();\n const result: Permission[] = [];\n\n for (const role of normalizeRoles(roles)) {\n const perms = ROLE_PERMISSIONS[role] ?? [];\n for (const perm of perms) {\n if (!seen.has(perm)) {\n seen.add(perm);\n result.push(perm);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Check a concrete permission list (e.g. authUser.permissions) for a grant.\n * Honours the \"*\" wildcard.\n */\nexport function permissionListIncludes(\n permissions: readonly Permission[] | null | undefined,\n permission: Permission,\n): boolean {\n if (!permissions?.length) return false;\n const set = new Set(permissions);\n if (set.has(WILDCARD_PERMISSION)) return true;\n return set.has(permission);\n}\n\nexport function hasPermission(\n roles: EnumUserRole[] | null | undefined,\n permission: Permission,\n): boolean {\n return permissionListIncludes(getPermissionsForRoles(roles), permission);\n}\n\nexport function hasAnyPermission(\n roles: EnumUserRole[] | null | undefined,\n permissions: readonly Permission[],\n): boolean {\n if (permissions.length === 0) return false;\n const granted = getPermissionsForRoles(roles);\n return permissions.some((p) => permissionListIncludes(granted, p));\n}\n\nexport function hasAllPermissions(\n roles: EnumUserRole[] | null | undefined,\n permissions: readonly Permission[],\n): boolean {\n if (permissions.length === 0) return true;\n const granted = getPermissionsForRoles(roles);\n return permissions.every((p) => permissionListIncludes(granted, p));\n}\n\nexport function hasRole(\n roles: EnumUserRole[] | null | undefined,\n role: EnumUserRole,\n): boolean {\n return normalizeRoles(roles).includes(role);\n}\n\nexport function hasAnyRole(\n roles: EnumUserRole[] | null | undefined,\n checkRoles: readonly EnumUserRole[],\n): boolean {\n if (checkRoles.length === 0) return false;\n const set = new Set(normalizeRoles(roles));\n return checkRoles.some((r) => set.has(r));\n}\n"],"mappings":"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","names":[]}
@@ -42,7 +42,7 @@ import {
42
42
  USER_FIELDS_FRAGMENT,
43
43
  VENDOR,
44
44
  VENDOR_INFO
45
- } from "./chunk-MIDSLTUJ.mjs";
45
+ } from "./chunk-UOFI3LKZ.mjs";
46
46
 
47
47
  // src/graphql/queries/post.ts
48
48
  import { gql as gql3 } from "@apollo/client";
@@ -3470,4 +3470,4 @@ export {
3470
3470
  useDeleteAffiliate,
3471
3471
  useRedeemAffiliateReward
3472
3472
  };
3473
- //# sourceMappingURL=chunk-WZPKYUSX.mjs.map
3473
+ //# sourceMappingURL=chunk-MOB5R5BF.mjs.map
@@ -179,8 +179,9 @@ var USER_FIELDS_FRAGMENT = gql`
179
179
  overallPoints
180
180
  platform
181
181
  preferredRegion
182
+ permissions
182
183
  promoCodes
183
- role
184
+ roles
184
185
  redeemedRewards {
185
186
  ...RedeemedRewardFields
186
187
  }
@@ -1211,4 +1212,4 @@ export {
1211
1212
  useGetUserActivities,
1212
1213
  useGetUserResources
1213
1214
  };
1214
- //# sourceMappingURL=chunk-MIDSLTUJ.mjs.map
1215
+ //# sourceMappingURL=chunk-UOFI3LKZ.mjs.map