@eaera-com/cms-sdk 0.1.77 → 0.1.78

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 (33) hide show
  1. package/dist/chunks/{_shared-DZlTUzoa.js → _shared-Dyz_Ya9z.js} +0 -1
  2. package/dist/chunks/{authz.constant-BAarvacV.js → authz.constant-BqX8Nzw6.js} +1 -1
  3. package/dist/common/constants/authz.constant.d.ts +11 -6
  4. package/dist/common/constants/authz.constant.d.ts.map +1 -1
  5. package/dist/common/utils/permission.d.ts +9 -0
  6. package/dist/common/utils/permission.d.ts.map +1 -0
  7. package/dist/core/createCmsSDK.d.ts.map +1 -1
  8. package/dist/core/sdk.type.d.ts +0 -6
  9. package/dist/core/sdk.type.d.ts.map +1 -1
  10. package/dist/index.js +37 -58
  11. package/dist/nuxt.d.ts +0 -6
  12. package/dist/nuxt.d.ts.map +1 -1
  13. package/dist/runtime/plugin.js +2 -8
  14. package/dist/server/auth/cbs-callback.post.js +1 -1
  15. package/dist/server/auth/cbs-start.post.js +1 -1
  16. package/dist/server/auth/idp-callback.get.js +1 -1
  17. package/dist/server/auth/idp-link-callback.get.js +1 -1
  18. package/dist/server/auth/idp-link-start.get.js +1 -1
  19. package/dist/server/auth/idp-link.post.js +1 -1
  20. package/dist/server/auth/idp-login.get.js +1 -1
  21. package/dist/server/auth/idp-me.get.js +1 -1
  22. package/dist/server/auth/idp-unlink.delete.js +1 -1
  23. package/dist/server/auth/login.post.js +1 -1
  24. package/dist/server/auth/logout.post.js +1 -1
  25. package/dist/server/auth/refresh.post.js +1 -1
  26. package/dist/server/authz/portal-access.get.js +5 -13
  27. package/dist/services/authz/authz.type.d.ts +5 -6
  28. package/dist/services/authz/authz.type.d.ts.map +1 -1
  29. package/dist/services/authz/index.d.ts +9 -10
  30. package/dist/services/authz/index.d.ts.map +1 -1
  31. package/dist/stores/authz.d.ts +18 -32
  32. package/dist/stores/authz.d.ts.map +1 -1
  33. package/package.json +1 -1
@@ -17,7 +17,6 @@ function readSdkConfig(event) {
17
17
  return {
18
18
  cmsUrl,
19
19
  clientId,
20
- portal: opts.portal,
21
20
  requestCasing: opts.requestCasing,
22
21
  responseCasing: opts.responseCasing
23
22
  };
@@ -1,5 +1,5 @@
1
1
  const AUTHZ_ENDPOINT = {
2
- portalAccess: (portal) => `/api/v1/authz/me/portals/${portal}`
2
+ portalAccess: () => `/api/v1/authz/me/portals`
3
3
  };
4
4
  const AUTHZ_PROXY_PATH = {
5
5
  PORTAL_ACCESS: "/portal-access"
@@ -1,18 +1,23 @@
1
1
  /**
2
- * Authz backend endpoints (engine RBAC surface).
2
+ * Authz backend endpoint (engine RBAC surface).
3
3
  *
4
- * GET /api/v1/authz/me/portals/{portal} — the caller's access to ONE
5
- * portal: `{ portal, has_access, permissions[], roles[] }`.
4
+ * GET /api/v1/authz/me/portals — the caller's effective grants:
5
+ * `{ userId, permissions[], roles[] }` (200 for any authenticated
6
+ * caller — there is no per-portal `has_access` flag or deny status on
7
+ * the wire). Portal-level access is a PERMISSION verdict: consumers
8
+ * gate their own access key (e.g. `people:portal:access`) against the
9
+ * returned grants via `useAuthzStore.can`.
6
10
  *
7
11
  * Error contract:
8
12
  * 401 UNAUTHENTICATED — token invalid/expired
9
13
  * 401 INVALID_TOKEN_AUDIENCE — token valid but minted for another portal
10
- * 403 PORTAL_ACCESS_DENIED — authenticated, no grant for this portal
11
14
  *
12
- * Path params are appended at call sites.
15
+ * (Legacy 403 `PORTAL_ACCESS_DENIED` from the old
16
+ * `/authz/me/portals/{portal}` route is still honoured by the store for
17
+ * back-compat with backends that predate this contract.)
13
18
  */
14
19
  export declare const AUTHZ_ENDPOINT: {
15
- readonly portalAccess: (portal: string) => string;
20
+ readonly portalAccess: () => string;
16
21
  };
17
22
  /**
18
23
  * Client→proxy route paths for authz flows (mirror of `AUTH_PROXY_PATH`).
@@ -1 +1 @@
1
- {"version":3,"file":"authz.constant.d.ts","sourceRoot":"","sources":["../../../src/common/constants/authz.constant.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc;oCACF,MAAM,KAAG,MAAM;CAC9B,CAAC;AAEX;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB;;CAEnB,CAAC"}
1
+ {"version":3,"file":"authz.constant.d.ts","sourceRoot":"","sources":["../../../src/common/constants/authz.constant.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,cAAc;iCACP,MAAM;CAChB,CAAC;AAEX;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB;;CAEnB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Wildcard-honouring permission matching for the engine's three-segment
3
+ * grammar (`domain:resource:action`). Single home for the matching rules —
4
+ * the authz store's `can` / `hasAnyPermission` / `hasAllPermissions` all
5
+ * delegate here.
6
+ */
7
+ /** True when any grant in `granted` covers `requested`. */
8
+ export declare function hasGrant(granted: string[], requested: string): boolean;
9
+ //# sourceMappingURL=permission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../../../src/common/utils/permission.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAmBH,2DAA2D;AAC3D,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEtE"}
@@ -1 +1 @@
1
- {"version":3,"file":"createCmsSDK.d.ts","sourceRoot":"","sources":["../../src/core/createCmsSDK.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAU,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGlE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAmP7D"}
1
+ {"version":3,"file":"createCmsSDK.d.ts","sourceRoot":"","sources":["../../src/core/createCmsSDK.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAU,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGlE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAkP7D"}
@@ -72,12 +72,6 @@ export interface ICmsSDKOptions {
72
72
  * atomically. When omitted, token-lifecycle flows call the backend directly.
73
73
  */
74
74
  authRoute?: $Fetch;
75
- /**
76
- * Default portal id for the portal-scoped authz flows
77
- * (`sdk.authz.portalAccess()`). The Nuxt module passes the module option
78
- * `cmsSdk.portal`. Per-call overrides win over this default.
79
- */
80
- portal?: string;
81
75
  }
82
76
  /** Map of backend name → typed fetcher, built from `endpoints`. */
83
77
  export type ApiMap = Record<string, $Fetch>;
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.type.d.ts","sourceRoot":"","sources":["../../src/core/sdk.type.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sdk.type.d.ts","sourceRoot":"","sources":["../../src/core/sdk.type.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { $fetch } from 'ofetch';
2
2
  import { H as HTTP_DEFAULTS, a as HTTP_RETRY_STATUS_CODES, b as HTTP_HEADER, R as RESPONSE_CASING_VALUE } from './chunks/http.constant-BzH5tJTG.js';
3
3
  export { S as SERIALIZATION_FORMAT } from './chunks/http.constant-BzH5tJTG.js';
4
4
  import { A as AUTH_PROXY_PATH, a as AUTH_ENDPOINT } from './chunks/auth.constant-CnGo0q42.js';
5
- import { A as AUTHZ_PROXY_PATH, a as AUTHZ_ENDPOINT } from './chunks/authz.constant-BAarvacV.js';
5
+ import { A as AUTHZ_PROXY_PATH, a as AUTHZ_ENDPOINT } from './chunks/authz.constant-BqX8Nzw6.js';
6
6
  import { C as COOKIE_SAME_SITE, a as COOKIE_DEFAULTS, T as TOKEN_STORAGE_KEY, P as PERSIST_KEY, S as STORE_PERSIST_KEY } from './chunks/storage.constant-CVWam5ls.js';
7
7
  export { b as PERSIST_ALLOWED_KEYS, c as PERSIST_MAX_BYTES, d as PERSIST_PREFIX, e as STORAGE_NAME } from './chunks/storage.constant-CVWam5ls.js';
8
8
  import { ref, shallowRef, watch, computed } from 'vue';
@@ -647,31 +647,18 @@ function createAuthzService(opts) {
647
647
  const { api, mock } = opts;
648
648
  const http = opts.routeApi ?? api;
649
649
  return {
650
- async portalAccess(portal) {
651
- const id = (portal || opts.portal?.() || "").trim();
652
- if (!id) {
653
- throw new Error(
654
- "authz.portalAccess: portal id is required — pass it or configure `cmsSdk.portal`"
655
- );
656
- }
650
+ async portalAccess() {
657
651
  if (mock()) {
658
- return { portal: id, hasAccess: true, permissions: ["*"], roles: [`${id}_operator`] };
659
- }
660
- if (opts.routeApi) {
661
- const res2 = await http(AUTHZ_PROXY_PATH.PORTAL_ACCESS, {
662
- query: { portal: id }
663
- });
664
- return _normalize(res2, id);
652
+ return { userId: null, permissions: ["*"], roles: ["operator"] };
665
653
  }
666
- const res = await api(AUTHZ_ENDPOINT.portalAccess(id));
667
- return _normalize(res, id);
654
+ const res = opts.routeApi ? await http(AUTHZ_PROXY_PATH.PORTAL_ACCESS) : await api(AUTHZ_ENDPOINT.portalAccess());
655
+ return _normalize(res);
668
656
  }
669
657
  };
670
658
  }
671
- function _normalize(res, portal) {
659
+ function _normalize(res) {
672
660
  return {
673
- portal: res.portal ?? portal,
674
- hasAccess: res.hasAccess ?? res.has_access ?? true,
661
+ userId: res.userId ?? res.user_id ?? null,
675
662
  permissions: res.permissions ?? [],
676
663
  roles: res.roles ?? []
677
664
  };
@@ -5512,8 +5499,7 @@ function createCmsSDK(options) {
5512
5499
  const authz = createAuthzService({
5513
5500
  api: apis.cms,
5514
5501
  routeApi: options.authRoute,
5515
- mock: () => mockState.enabled,
5516
- portal: () => options.portal
5502
+ mock: () => mockState.enabled
5517
5503
  });
5518
5504
  const content = createContentService({
5519
5505
  api: apis.cms,
@@ -7240,17 +7226,29 @@ function _noSdk$a() {
7240
7226
  return new Error("Auth store: SDK not attached. Call setSdk() first.");
7241
7227
  }
7242
7228
 
7229
+ function permissionMatches(granted, requested) {
7230
+ if (granted === "*") return true;
7231
+ const g = granted.split(":");
7232
+ if (g.every((seg) => seg === "*")) return true;
7233
+ const r = requested.split(":");
7234
+ if (g.length > r.length) return false;
7235
+ if (!g.every((seg, i) => seg === "*" || seg === r[i])) return false;
7236
+ if (g.length < r.length && g.at(-1) !== "*") return false;
7237
+ return true;
7238
+ }
7239
+ function hasGrant(granted, requested) {
7240
+ return granted.some((g) => permissionMatches(g, requested));
7241
+ }
7242
+
7243
7243
  const useAuthzStore = defineStore(
7244
7244
  "cms-authz",
7245
7245
  () => {
7246
7246
  const sdk = shallowRef(null);
7247
- const portal = ref("");
7248
7247
  const portalAccess = ref(null);
7249
7248
  const loaded = ref(false);
7250
7249
  const isLoading = ref(false);
7251
7250
  const errorCode = ref("");
7252
7251
  let inFlight = null;
7253
- const hasAccess = computed(() => portalAccess.value?.hasAccess ?? false);
7254
7252
  const permissions = computed(() => portalAccess.value?.permissions ?? []);
7255
7253
  const roles = computed(() => portalAccess.value?.roles ?? []);
7256
7254
  const SESSION_INVALID_CODES = /* @__PURE__ */ new Set([
@@ -7263,26 +7261,21 @@ const useAuthzStore = defineStore(
7263
7261
  );
7264
7262
  const isAccessDenied = computed(() => loaded.value && errorCode.value === ACCESS_DENIED_CODE);
7265
7263
  const can = (permission) => {
7266
- if (!loaded.value || !hasAccess.value) return false;
7267
- return permissions.value.some((g) => _permissionMatches(g, permission));
7264
+ if (!loaded.value) return false;
7265
+ return hasGrant(permissions.value, permission);
7268
7266
  };
7269
7267
  const hasRole = (role) => roles.value.includes(role);
7270
7268
  const hasAnyPermission = (list) => {
7271
- if (!loaded.value || !hasAccess.value) return false;
7272
- const granted = permissions.value;
7273
- return list.some((p) => granted.some((g) => _permissionMatches(g, p)));
7269
+ if (!loaded.value) return false;
7270
+ return list.some((p) => hasGrant(permissions.value, p));
7274
7271
  };
7275
7272
  const hasAllPermissions = (list) => {
7276
- if (!loaded.value || !hasAccess.value) return false;
7277
- const granted = permissions.value;
7278
- return list.every((p) => granted.some((g) => _permissionMatches(g, p)));
7273
+ if (!loaded.value) return false;
7274
+ return list.every((p) => hasGrant(permissions.value, p));
7279
7275
  };
7280
7276
  const setSdk = (instance) => {
7281
7277
  sdk.value = instance;
7282
7278
  };
7283
- const setPortal = (id) => {
7284
- portal.value = id;
7285
- };
7286
7279
  const _reset = () => {
7287
7280
  portalAccess.value = null;
7288
7281
  loaded.value = false;
@@ -7292,13 +7285,12 @@ const useAuthzStore = defineStore(
7292
7285
  };
7293
7286
  const loadPortalAccess = async (opts) => {
7294
7287
  if (!sdk.value) throw new Error("Authz store: SDK not attached. Call setSdk() first.");
7295
- if (opts?.portal) portal.value = opts.portal;
7296
7288
  if (loaded.value && !opts?.force) return;
7297
7289
  if (inFlight) return inFlight;
7298
7290
  isLoading.value = true;
7299
7291
  inFlight = (async () => {
7300
7292
  try {
7301
- portalAccess.value = await sdk.value.authz.portalAccess(portal.value || void 0);
7293
+ portalAccess.value = await sdk.value.authz.portalAccess();
7302
7294
  errorCode.value = "";
7303
7295
  } catch (e) {
7304
7296
  portalAccess.value = null;
@@ -7330,20 +7322,17 @@ const useAuthzStore = defineStore(
7330
7322
  );
7331
7323
  return {
7332
7324
  // state
7333
- portal,
7334
7325
  portalAccess,
7335
7326
  loaded,
7336
7327
  isLoading,
7337
7328
  errorCode,
7338
7329
  // getters
7339
- hasAccess,
7340
7330
  permissions,
7341
7331
  roles,
7342
7332
  isSessionInvalid,
7343
7333
  isAccessDenied,
7344
7334
  // actions
7345
7335
  setSdk,
7346
- setPortal,
7347
7336
  loadPortalAccess,
7348
7337
  can,
7349
7338
  hasRole,
@@ -7352,16 +7341,16 @@ const useAuthzStore = defineStore(
7352
7341
  };
7353
7342
  },
7354
7343
  {
7355
- // Rehydrate the portal-access cache across reloads — `permissions`,
7356
- // `roles`, and `hasAccess` are computeds derived from `portalAccess`,
7357
- // so persisting the source (plus `loaded` so `can()` trusts the cache
7358
- // on the first render after F5, per the store contract "read the cache,
7359
- // never fetch before rendering") restores the full authorization
7360
- // surface. App-level session-restore middleware is expected to call
7344
+ // Rehydrate the grants cache across reloads — `permissions` and `roles`
7345
+ // are computeds derived from `portalAccess`, so persisting the source
7346
+ // (plus `loaded` so `can()` trusts the cache on the first render after
7347
+ // F5, per the store contract "read the cache, never fetch before
7348
+ // rendering") restores the full authorization surface. App-level
7349
+ // session-restore middleware is expected to call
7361
7350
  // `loadPortalAccess({ force: true })` afterwards to refresh from the
7362
7351
  // server — same fetch-on-restore contract as login / `loginEpoch` bump.
7363
- // Size: `IPortalAccess` is `{ portal, hasAccess, permissions[], roles[] }`,
7364
- // well under the `PERSIST_MAX_BYTES` cookie cap.
7352
+ // Size: `IPortalAccess` is `{ userId, permissions[], roles[] }`, well
7353
+ // under the `PERSIST_MAX_BYTES` cookie cap.
7365
7354
  persist: {
7366
7355
  key: STORE_PERSIST_KEY.AUTHZ,
7367
7356
  pick: ["portalAccess", "loaded", "errorCode"]
@@ -7375,16 +7364,6 @@ function _extractErrorCode(e) {
7375
7364
  const code = detail?.code;
7376
7365
  return typeof code === "string" ? code : "";
7377
7366
  }
7378
- function _permissionMatches(granted, requested) {
7379
- if (granted === "*") return true;
7380
- const g = granted.split(":");
7381
- if (g.every((seg) => seg === "*")) return true;
7382
- const r = requested.split(":");
7383
- if (g.length > r.length) return false;
7384
- if (!g.every((seg, i) => seg === "*" || seg === r[i])) return false;
7385
- if (g.length < r.length && g.at(-1) !== "*") return false;
7386
- return true;
7387
- }
7388
7367
 
7389
7368
  const useBarsStore = defineStore(
7390
7369
  "cms-bars",
package/dist/nuxt.d.ts CHANGED
@@ -29,12 +29,6 @@ export interface IModuleOptions {
29
29
  * Set `false` for consumers that prefer explicit `useWsStore().open()`.
30
30
  */
31
31
  wsAutoOpen?: boolean;
32
- /**
33
- * Portal id used by the portal-scoped authz flows
34
- * (`useAuthzStore().loadPortalAccess()` → `GET /api/v1/authz/me/portals/{portal}`).
35
- * e.g. `'people'` for People Hub, `'backoffice'` for the admin portal.
36
- */
37
- portal?: string;
38
32
  }
39
33
  /**
40
34
  * Nuxt module: registers a plugin that builds the CMS SDK from runtime
@@ -1 +1 @@
1
- {"version":3,"file":"nuxt.d.ts","sourceRoot":"","sources":["../src/nuxt.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAEvE,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,kFAAkF;IAClF,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAqBD;;;;;;;;;;;;;GAaG;;AACH,wBA+BG"}
1
+ {"version":3,"file":"nuxt.d.ts","sourceRoot":"","sources":["../src/nuxt.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAEvE,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,kFAAkF;IAClF,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAqBD;;;;;;;;;;;;;GAaG;;AACH,wBA+BG"}
@@ -109,8 +109,7 @@ const plugin = defineNuxtPlugin(async (nuxtApp) => {
109
109
  refresh,
110
110
  responseCasing: opts.responseCasing,
111
111
  requestCasing: opts.requestCasing,
112
- authRoute,
113
- portal: opts.portal
112
+ authRoute
114
113
  });
115
114
  sdkInstance = sdk;
116
115
  const pinia = nuxtApp.$pinia;
@@ -129,12 +128,7 @@ const plugin = defineNuxtPlugin(async (nuxtApp) => {
129
128
  } catch (e) {
130
129
  console.warn("[cms-sdk] persistence plugin install failed:", e);
131
130
  }
132
- const { authStore, authzStore, wsStore } = attachStores(pinia, sdk);
133
- try {
134
- authzStore?.setPortal?.(opts.portal ?? "");
135
- } catch (e) {
136
- console.warn("[cms-sdk] could not seed authz portal:", e);
137
- }
131
+ const { authStore, wsStore } = attachStores(pinia, sdk);
138
132
  try {
139
133
  if (import.meta.server) {
140
134
  const token = useCookie(TOKEN_STORAGE_KEY).value;
@@ -2,7 +2,7 @@ import { defineEventHandler, createError, readBody, parseCookies, getRequestHead
2
2
  import { $fetch } from 'ofetch';
3
3
  import { a as AUTH_ENDPOINT } from '../../chunks/auth.constant-CnGo0q42.js';
4
4
  import { b as HTTP_HEADER } from '../../chunks/http.constant-BzH5tJTG.js';
5
- import { r as readSdkConfig, T as TOKEN_COOKIE_OPTIONS } from '../../chunks/_shared-DZlTUzoa.js';
5
+ import { r as readSdkConfig, T as TOKEN_COOKIE_OPTIONS } from '../../chunks/_shared-Dyz_Ya9z.js';
6
6
  import { T as TOKEN_STORAGE_KEY, R as REFRESH_TOKEN_STORAGE_KEY } from '../../chunks/storage.constant-CVWam5ls.js';
7
7
 
8
8
  const cbsCallback_post = defineEventHandler(async (event) => {
@@ -2,7 +2,7 @@ import { defineEventHandler, createError, parseCookies, getRequestHeader } from
2
2
  import { $fetch } from 'ofetch';
3
3
  import { a as AUTH_ENDPOINT } from '../../chunks/auth.constant-CnGo0q42.js';
4
4
  import { b as HTTP_HEADER } from '../../chunks/http.constant-BzH5tJTG.js';
5
- import { r as readSdkConfig } from '../../chunks/_shared-DZlTUzoa.js';
5
+ import { r as readSdkConfig } from '../../chunks/_shared-Dyz_Ya9z.js';
6
6
 
7
7
  const cbsStart_post = defineEventHandler(async (event) => {
8
8
  const { cmsUrl, clientId } = readSdkConfig(event);
@@ -2,7 +2,7 @@ import { defineEventHandler, createError, getQuery, parseCookies, getRequestHead
2
2
  import { $fetch } from 'ofetch';
3
3
  import { a as AUTH_ENDPOINT } from '../../chunks/auth.constant-CnGo0q42.js';
4
4
  import { b as HTTP_HEADER } from '../../chunks/http.constant-BzH5tJTG.js';
5
- import { r as readSdkConfig, T as TOKEN_COOKIE_OPTIONS } from '../../chunks/_shared-DZlTUzoa.js';
5
+ import { r as readSdkConfig, T as TOKEN_COOKIE_OPTIONS } from '../../chunks/_shared-Dyz_Ya9z.js';
6
6
  import { T as TOKEN_STORAGE_KEY, R as REFRESH_TOKEN_STORAGE_KEY } from '../../chunks/storage.constant-CVWam5ls.js';
7
7
 
8
8
  const idpCallback_get = defineEventHandler(async (event) => {
@@ -2,7 +2,7 @@ import { defineEventHandler, createError, getQuery, parseCookies } from 'h3';
2
2
  import { $fetch } from 'ofetch';
3
3
  import { a as AUTH_ENDPOINT } from '../../chunks/auth.constant-CnGo0q42.js';
4
4
  import { b as HTTP_HEADER } from '../../chunks/http.constant-BzH5tJTG.js';
5
- import { r as readSdkConfig } from '../../chunks/_shared-DZlTUzoa.js';
5
+ import { r as readSdkConfig } from '../../chunks/_shared-Dyz_Ya9z.js';
6
6
  import { T as TOKEN_STORAGE_KEY } from '../../chunks/storage.constant-CVWam5ls.js';
7
7
 
8
8
  const idpLinkCallback_get = defineEventHandler(async (event) => {
@@ -2,7 +2,7 @@ import { defineEventHandler, createError, getQuery, parseCookies } from 'h3';
2
2
  import { $fetch } from 'ofetch';
3
3
  import { a as AUTH_ENDPOINT } from '../../chunks/auth.constant-CnGo0q42.js';
4
4
  import { b as HTTP_HEADER } from '../../chunks/http.constant-BzH5tJTG.js';
5
- import { r as readSdkConfig } from '../../chunks/_shared-DZlTUzoa.js';
5
+ import { r as readSdkConfig } from '../../chunks/_shared-Dyz_Ya9z.js';
6
6
  import { T as TOKEN_STORAGE_KEY } from '../../chunks/storage.constant-CVWam5ls.js';
7
7
 
8
8
  const idpLinkStart_get = defineEventHandler(async (event) => {
@@ -2,7 +2,7 @@ import { defineEventHandler, createError, readBody, parseCookies } from 'h3';
2
2
  import { $fetch } from 'ofetch';
3
3
  import { a as AUTH_ENDPOINT } from '../../chunks/auth.constant-CnGo0q42.js';
4
4
  import { b as HTTP_HEADER } from '../../chunks/http.constant-BzH5tJTG.js';
5
- import { r as readSdkConfig } from '../../chunks/_shared-DZlTUzoa.js';
5
+ import { r as readSdkConfig } from '../../chunks/_shared-Dyz_Ya9z.js';
6
6
  import { T as TOKEN_STORAGE_KEY } from '../../chunks/storage.constant-CVWam5ls.js';
7
7
 
8
8
  const idpLink_post = defineEventHandler(async (event) => {
@@ -2,7 +2,7 @@ import { defineEventHandler, createError, getQuery, parseCookies, getRequestHead
2
2
  import { $fetch } from 'ofetch';
3
3
  import { a as AUTH_ENDPOINT } from '../../chunks/auth.constant-CnGo0q42.js';
4
4
  import { b as HTTP_HEADER } from '../../chunks/http.constant-BzH5tJTG.js';
5
- import { r as readSdkConfig } from '../../chunks/_shared-DZlTUzoa.js';
5
+ import { r as readSdkConfig } from '../../chunks/_shared-Dyz_Ya9z.js';
6
6
 
7
7
  const idpLogin_get = defineEventHandler(async (event) => {
8
8
  const { cmsUrl, clientId } = readSdkConfig(event);
@@ -2,7 +2,7 @@ import { defineEventHandler, createError, parseCookies } from 'h3';
2
2
  import { $fetch } from 'ofetch';
3
3
  import { a as AUTH_ENDPOINT } from '../../chunks/auth.constant-CnGo0q42.js';
4
4
  import { b as HTTP_HEADER } from '../../chunks/http.constant-BzH5tJTG.js';
5
- import { r as readSdkConfig } from '../../chunks/_shared-DZlTUzoa.js';
5
+ import { r as readSdkConfig } from '../../chunks/_shared-Dyz_Ya9z.js';
6
6
  import { T as TOKEN_STORAGE_KEY } from '../../chunks/storage.constant-CVWam5ls.js';
7
7
 
8
8
  const idpMe_get = defineEventHandler(async (event) => {
@@ -2,7 +2,7 @@ import { defineEventHandler, createError, getQuery, parseCookies } from 'h3';
2
2
  import { $fetch } from 'ofetch';
3
3
  import { a as AUTH_ENDPOINT } from '../../chunks/auth.constant-CnGo0q42.js';
4
4
  import { b as HTTP_HEADER } from '../../chunks/http.constant-BzH5tJTG.js';
5
- import { r as readSdkConfig } from '../../chunks/_shared-DZlTUzoa.js';
5
+ import { r as readSdkConfig } from '../../chunks/_shared-Dyz_Ya9z.js';
6
6
  import { T as TOKEN_STORAGE_KEY } from '../../chunks/storage.constant-CVWam5ls.js';
7
7
 
8
8
  const idpUnlink_delete = defineEventHandler(async (event) => {
@@ -2,7 +2,7 @@ import { defineEventHandler, createError, readBody, parseCookies, getRequestHead
2
2
  import { $fetch } from 'ofetch';
3
3
  import { a as AUTH_ENDPOINT } from '../../chunks/auth.constant-CnGo0q42.js';
4
4
  import { b as HTTP_HEADER } from '../../chunks/http.constant-BzH5tJTG.js';
5
- import { r as readSdkConfig, T as TOKEN_COOKIE_OPTIONS } from '../../chunks/_shared-DZlTUzoa.js';
5
+ import { r as readSdkConfig, T as TOKEN_COOKIE_OPTIONS } from '../../chunks/_shared-Dyz_Ya9z.js';
6
6
  import { T as TOKEN_STORAGE_KEY, R as REFRESH_TOKEN_STORAGE_KEY } from '../../chunks/storage.constant-CVWam5ls.js';
7
7
 
8
8
  const login_post = defineEventHandler(async (event) => {
@@ -2,7 +2,7 @@ import { defineEventHandler, parseCookies, deleteCookie } from 'h3';
2
2
  import { $fetch } from 'ofetch';
3
3
  import { a as AUTH_ENDPOINT } from '../../chunks/auth.constant-CnGo0q42.js';
4
4
  import { b as HTTP_HEADER } from '../../chunks/http.constant-BzH5tJTG.js';
5
- import { r as readSdkConfig, T as TOKEN_COOKIE_OPTIONS } from '../../chunks/_shared-DZlTUzoa.js';
5
+ import { r as readSdkConfig, T as TOKEN_COOKIE_OPTIONS } from '../../chunks/_shared-Dyz_Ya9z.js';
6
6
  import { T as TOKEN_STORAGE_KEY, R as REFRESH_TOKEN_STORAGE_KEY } from '../../chunks/storage.constant-CVWam5ls.js';
7
7
 
8
8
  const logout_post = defineEventHandler(async (event) => {
@@ -2,7 +2,7 @@ import { defineEventHandler, createError, parseCookies, setCookie } from 'h3';
2
2
  import { $fetch } from 'ofetch';
3
3
  import { a as AUTH_ENDPOINT } from '../../chunks/auth.constant-CnGo0q42.js';
4
4
  import { b as HTTP_HEADER, R as RESPONSE_CASING_VALUE } from '../../chunks/http.constant-BzH5tJTG.js';
5
- import { r as readSdkConfig, T as TOKEN_COOKIE_OPTIONS } from '../../chunks/_shared-DZlTUzoa.js';
5
+ import { r as readSdkConfig, T as TOKEN_COOKIE_OPTIONS } from '../../chunks/_shared-Dyz_Ya9z.js';
6
6
  import { R as REFRESH_TOKEN_STORAGE_KEY, T as TOKEN_STORAGE_KEY } from '../../chunks/storage.constant-CVWam5ls.js';
7
7
 
8
8
  const refresh_post = defineEventHandler(async (event) => {
@@ -1,26 +1,18 @@
1
- import { defineEventHandler, createError, getQuery, parseCookies } from 'h3';
1
+ import { defineEventHandler, createError, parseCookies } from 'h3';
2
2
  import { $fetch } from 'ofetch';
3
- import { a as AUTHZ_ENDPOINT } from '../../chunks/authz.constant-BAarvacV.js';
3
+ import { a as AUTHZ_ENDPOINT } from '../../chunks/authz.constant-BqX8Nzw6.js';
4
4
  import { b as HTTP_HEADER } from '../../chunks/http.constant-BzH5tJTG.js';
5
- import { r as readSdkConfig } from '../../chunks/_shared-DZlTUzoa.js';
5
+ import { r as readSdkConfig } from '../../chunks/_shared-Dyz_Ya9z.js';
6
6
  import { T as TOKEN_STORAGE_KEY } from '../../chunks/storage.constant-CVWam5ls.js';
7
7
 
8
8
  const portalAccess_get = defineEventHandler(async (event) => {
9
- const { cmsUrl, clientId, portal: defaultPortal } = readSdkConfig(event);
9
+ const { cmsUrl, clientId } = readSdkConfig(event);
10
10
  if (!cmsUrl) throw createError({ statusCode: 500, message: "CMS URL not configured" });
11
- const query = getQuery(event);
12
- const portal = String(query.portal ?? defaultPortal ?? "").trim();
13
- if (!portal) {
14
- throw createError({
15
- statusCode: 400,
16
- message: "portal is required (query param or cmsSdk.portal module option)"
17
- });
18
- }
19
11
  const cookies = parseCookies(event);
20
12
  const token = cookies[TOKEN_STORAGE_KEY] || "";
21
13
  if (!token) throw createError({ statusCode: 401, message: "Not authenticated" });
22
14
  try {
23
- return await $fetch(AUTHZ_ENDPOINT.portalAccess(portal), {
15
+ return await $fetch(AUTHZ_ENDPOINT.portalAccess(), {
24
16
  baseURL: cmsUrl,
25
17
  headers: {
26
18
  [HTTP_HEADER.CLIENT_ID]: clientId || "",
@@ -2,14 +2,13 @@
2
2
  * Authz domain DTOs (engine RBAC surface).
3
3
  *
4
4
  * Field names are camelCase per the SDK public-surface convention; the
5
- * backend wire shape is snake_case (`has_access`) and is normalised by the
6
- * service. No tokens travel here — the access check is a pure read.
5
+ * backend wire shape arrives camelCase too (`userId` the CMS casing
6
+ * middleware rewrites response bodies). No tokens travel here — the
7
+ * access check is a pure read.
7
8
  */
8
9
  export interface IPortalAccess {
9
- /** Portal id the access was resolved for (e.g. `people`). */
10
- portal: string;
11
- /** False only on an explicit deny — a denial status throws instead. */
12
- hasAccess: boolean;
10
+ /** Caller id resolved by the engine (null when absent on the wire). */
11
+ userId: number | null;
13
12
  /**
14
13
  * Effective permission codes, e.g. `people:catalog:view`.
15
14
  * `['*']` means wildcard (grant-all) — consumers should honour it.
@@ -1 +1 @@
1
- {"version":3,"file":"authz.type.d.ts","sourceRoot":"","sources":["../../../src/services/authz/authz.type.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,SAAS,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,sDAAsD;IACtD,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB"}
1
+ {"version":3,"file":"authz.type.d.ts","sourceRoot":"","sources":["../../../src/services/authz/authz.type.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;;;OAGG;IACH,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,sDAAsD;IACtD,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB"}
@@ -15,24 +15,23 @@ export interface IAuthzServiceOptions {
15
15
  routeApi?: $Fetch;
16
16
  /** Lazy flag — when true, the service returns fake data. */
17
17
  mock: () => boolean;
18
- /** Default portal id (Nuxt module option `cmsSdk.portal`). Per-call override wins. */
19
- portal?: () => string | undefined;
20
18
  }
21
19
  export interface IAuthzService {
22
20
  /**
23
- * Resolve the caller's access to a portal
24
- * (`GET /api/v1/authz/me/portals/{portal}`).
21
+ * Resolve the caller's effective grants (`GET /api/v1/authz/me/portals`).
22
+ * Consumers decide access by checking their portal's gate key against
23
+ * `permissions` (e.g. via `useAuthzStore.can('people:portal:access')`).
25
24
  *
26
25
  * Throws on the documented error statuses so callers can branch:
27
- * 401 `UNAUTHENTICATED` / `INVALID_TOKEN_AUDIENCE`,
28
- * 403 `PORTAL_ACCESS_DENIED` (codes survive in the error payload's
29
- * `data` via the proxy's `authBackendError` / `extractAuthError`).
26
+ * 401 `UNAUTHENTICATED` / `INVALID_TOKEN_AUDIENCE`
27
+ * (codes survive in the error payload's `data` via the proxy's
28
+ * `authBackendError` / `extractAuthError`).
30
29
  */
31
- portalAccess(portal?: string): Promise<IPortalAccess>;
30
+ portalAccess(): Promise<IPortalAccess>;
32
31
  }
33
32
  /**
34
- * Authz domain service. Mirrors the engine RBAC surface used by every
35
- * portal: "am I allowed into THIS portal, and with which permissions/roles".
33
+ * Authz domain service. Mirrors the engine RBAC surface: the caller's
34
+ * effective permissions and roles.
36
35
  *
37
36
  * The result is cheap to refetch and MUST be re-resolved on login and on
38
37
  * session restore (page refresh) — caching across sessions is deliberately
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/authz/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,WAAW,oBAAoB;IACnC,qDAAqD;IACrD,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,IAAI,EAAE,MAAM,OAAO,CAAC;IACpB,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,WAAW,aAAa;IAC5B;;;;;;;;OAQG;IACH,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CACvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,oBAAoB,GAAG,aAAa,CA6B5E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/authz/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,WAAW,oBAAoB;IACnC,qDAAqD;IACrD,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,IAAI,EAAE,MAAM,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B;;;;;;;;;OASG;IACH,YAAY,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;CACxC;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,oBAAoB,GAAG,aAAa,CAkB5E"}
@@ -1,8 +1,8 @@
1
1
  import { ICmsSDK } from '../core/sdk.type';
2
2
  import { IPortalAccess } from '../services/authz';
3
3
  /**
4
- * Authz store — portal-access domain state (permissions, roles, deny
5
- * status) with the canonical fetch-once cache.
4
+ * Authz store — authorization domain state (permissions, roles) with the
5
+ * canonical fetch-once cache.
6
6
  *
7
7
  * The call contract for every portal:
8
8
  * - fetch on login success,
@@ -15,102 +15,88 @@ import { IPortalAccess } from '../services/authz';
15
15
  * the auth store — silent sliding token rotation does NOT invalidate) and
16
16
  * reset on logout, so a fresh login always re-resolves access.
17
17
  *
18
- * Consumers branch on `errorCode` for the documented failures:
19
- * `UNAUTHENTICATED`, `INVALID_TOKEN_AUDIENCE` (session unusable for this
20
- * portal) and `PORTAL_ACCESS_DENIED` (authenticated, no grant).
18
+ * The endpoint (`GET /api/v1/authz/me/portals`) returns the caller's
19
+ * effective grants only there is no access flag on the wire. Consumers
20
+ * gate their portal's access key themselves (e.g. `can('people:portal:access')`
21
+ * in the route middleware). Consumers branch on `errorCode` for the
22
+ * documented failures: `UNAUTHENTICATED` / `INVALID_TOKEN_AUDIENCE`
23
+ * (session unusable for this portal) and a legacy 403
24
+ * `PORTAL_ACCESS_DENIED` (still honoured for older backends).
21
25
  */
22
26
  export declare const useAuthzStore: import('pinia').StoreDefinition<"cms-authz", Pick<{
23
- portal: import('vue').Ref<string, string>;
24
27
  portalAccess: import('vue').Ref<{
25
- portal: string;
26
- hasAccess: boolean;
28
+ userId: number | null;
27
29
  permissions: string[];
28
30
  roles: string[];
29
31
  } | null, IPortalAccess | {
30
- portal: string;
31
- hasAccess: boolean;
32
+ userId: number | null;
32
33
  permissions: string[];
33
34
  roles: string[];
34
35
  } | null>;
35
36
  loaded: import('vue').Ref<boolean, boolean>;
36
37
  isLoading: import('vue').Ref<boolean, boolean>;
37
38
  errorCode: import('vue').Ref<string, string>;
38
- hasAccess: import('vue').ComputedRef<boolean>;
39
39
  permissions: import('vue').ComputedRef<string[]>;
40
40
  roles: import('vue').ComputedRef<string[]>;
41
41
  isSessionInvalid: import('vue').ComputedRef<boolean>;
42
42
  isAccessDenied: import('vue').ComputedRef<boolean>;
43
43
  setSdk: (instance: ICmsSDK) => void;
44
- setPortal: (id: string) => void;
45
44
  loadPortalAccess: (opts?: {
46
45
  force?: boolean;
47
- portal?: string;
48
46
  }) => Promise<void>;
49
47
  can: (permission: string) => boolean;
50
48
  hasRole: (role: string) => boolean;
51
49
  hasAnyPermission: (list: string[]) => boolean;
52
50
  hasAllPermissions: (list: string[]) => boolean;
53
- }, "portal" | "portalAccess" | "loaded" | "errorCode" | "isLoading">, Pick<{
54
- portal: import('vue').Ref<string, string>;
51
+ }, "portalAccess" | "loaded" | "errorCode" | "isLoading">, Pick<{
55
52
  portalAccess: import('vue').Ref<{
56
- portal: string;
57
- hasAccess: boolean;
53
+ userId: number | null;
58
54
  permissions: string[];
59
55
  roles: string[];
60
56
  } | null, IPortalAccess | {
61
- portal: string;
62
- hasAccess: boolean;
57
+ userId: number | null;
63
58
  permissions: string[];
64
59
  roles: string[];
65
60
  } | null>;
66
61
  loaded: import('vue').Ref<boolean, boolean>;
67
62
  isLoading: import('vue').Ref<boolean, boolean>;
68
63
  errorCode: import('vue').Ref<string, string>;
69
- hasAccess: import('vue').ComputedRef<boolean>;
70
64
  permissions: import('vue').ComputedRef<string[]>;
71
65
  roles: import('vue').ComputedRef<string[]>;
72
66
  isSessionInvalid: import('vue').ComputedRef<boolean>;
73
67
  isAccessDenied: import('vue').ComputedRef<boolean>;
74
68
  setSdk: (instance: ICmsSDK) => void;
75
- setPortal: (id: string) => void;
76
69
  loadPortalAccess: (opts?: {
77
70
  force?: boolean;
78
- portal?: string;
79
71
  }) => Promise<void>;
80
72
  can: (permission: string) => boolean;
81
73
  hasRole: (role: string) => boolean;
82
74
  hasAnyPermission: (list: string[]) => boolean;
83
75
  hasAllPermissions: (list: string[]) => boolean;
84
- }, "hasAccess" | "permissions" | "roles" | "isSessionInvalid" | "isAccessDenied">, Pick<{
85
- portal: import('vue').Ref<string, string>;
76
+ }, "permissions" | "roles" | "isSessionInvalid" | "isAccessDenied">, Pick<{
86
77
  portalAccess: import('vue').Ref<{
87
- portal: string;
88
- hasAccess: boolean;
78
+ userId: number | null;
89
79
  permissions: string[];
90
80
  roles: string[];
91
81
  } | null, IPortalAccess | {
92
- portal: string;
93
- hasAccess: boolean;
82
+ userId: number | null;
94
83
  permissions: string[];
95
84
  roles: string[];
96
85
  } | null>;
97
86
  loaded: import('vue').Ref<boolean, boolean>;
98
87
  isLoading: import('vue').Ref<boolean, boolean>;
99
88
  errorCode: import('vue').Ref<string, string>;
100
- hasAccess: import('vue').ComputedRef<boolean>;
101
89
  permissions: import('vue').ComputedRef<string[]>;
102
90
  roles: import('vue').ComputedRef<string[]>;
103
91
  isSessionInvalid: import('vue').ComputedRef<boolean>;
104
92
  isAccessDenied: import('vue').ComputedRef<boolean>;
105
93
  setSdk: (instance: ICmsSDK) => void;
106
- setPortal: (id: string) => void;
107
94
  loadPortalAccess: (opts?: {
108
95
  force?: boolean;
109
- portal?: string;
110
96
  }) => Promise<void>;
111
97
  can: (permission: string) => boolean;
112
98
  hasRole: (role: string) => boolean;
113
99
  hasAnyPermission: (list: string[]) => boolean;
114
100
  hasAllPermissions: (list: string[]) => boolean;
115
- }, "setSdk" | "setPortal" | "loadPortalAccess" | "can" | "hasRole" | "hasAnyPermission" | "hasAllPermissions">>;
101
+ }, "setSdk" | "loadPortalAccess" | "can" | "hasRole" | "hasAnyPermission" | "hasAllPermissions">>;
116
102
  //# sourceMappingURL=authz.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"authz.d.ts","sourceRoot":"","sources":["../../src/stores/authz.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;uBA6DI,OAAO,KAAG,IAAI;oBAIjB,MAAM,KAAG,IAAI;8BAiBG;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAG,OAAO,CAAC,IAAI,CAAC;sBAxClE,MAAM,KAAG,OAAO;oBAKlB,MAAM,KAAG,OAAO;6BAEP,MAAM,EAAE,KAAG,OAAO;8BAMjB,MAAM,EAAE,KAAG,OAAO;;;;;;;;;;;;;;;;;;;;;;uBAMzB,OAAO,KAAG,IAAI;oBAIjB,MAAM,KAAG,IAAI;8BAiBG;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAG,OAAO,CAAC,IAAI,CAAC;sBAxClE,MAAM,KAAG,OAAO;oBAKlB,MAAM,KAAG,OAAO;6BAEP,MAAM,EAAE,KAAG,OAAO;8BAMjB,MAAM,EAAE,KAAG,OAAO;;;;;;;;;;;;;;;;;;;;;;uBAMzB,OAAO,KAAG,IAAI;oBAIjB,MAAM,KAAG,IAAI;8BAiBG;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAG,OAAO,CAAC,IAAI,CAAC;sBAxClE,MAAM,KAAG,OAAO;oBAKlB,MAAM,KAAG,OAAO;6BAEP,MAAM,EAAE,KAAG,OAAO;8BAMjB,MAAM,EAAE,KAAG,OAAO;+GAgHtD,CAAC"}
1
+ {"version":3,"file":"authz.d.ts","sourceRoot":"","sources":["../../src/stores/authz.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAIhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;uBAwDI,OAAO,KAAG,IAAI;8BAiBD;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,KAAG,OAAO,CAAC,IAAI,CAAC;sBAlCjD,MAAM,KAAG,OAAO;oBAKlB,MAAM,KAAG,OAAO;6BAEP,MAAM,EAAE,KAAG,OAAO;8BAKjB,MAAM,EAAE,KAAG,OAAO;;;;;;;;;;;;;;;;;;uBAKzB,OAAO,KAAG,IAAI;8BAiBD;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,KAAG,OAAO,CAAC,IAAI,CAAC;sBAlCjD,MAAM,KAAG,OAAO;oBAKlB,MAAM,KAAG,OAAO;6BAEP,MAAM,EAAE,KAAG,OAAO;8BAKjB,MAAM,EAAE,KAAG,OAAO;;;;;;;;;;;;;;;;;;uBAKzB,OAAO,KAAG,IAAI;8BAiBD;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,KAAG,OAAO,CAAC,IAAI,CAAC;sBAlCjD,MAAM,KAAG,OAAO;oBAKlB,MAAM,KAAG,OAAO;6BAEP,MAAM,EAAE,KAAG,OAAO;8BAKjB,MAAM,EAAE,KAAG,OAAO;iGAuGtD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eaera-com/cms-sdk",
3
- "version": "0.1.77",
3
+ "version": "0.1.78",
4
4
  "description": "EAERA CMS SDK — data access layer for Nuxt 3 apps (ofetch + Pinia + typed services)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",