@liquisio/wix-access 0.5.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -4
- package/backend.d.ts +48 -2
- package/backend.js +3 -3
- package/package.json +1 -1
- package/public.d.ts +10 -2
- package/public.js +2 -2
- package/types.d.ts +171 -0
package/README.md
CHANGED
|
@@ -224,9 +224,114 @@ $w.onReady(async () => {
|
|
|
224
224
|
})
|
|
225
225
|
```
|
|
226
226
|
|
|
227
|
-
> **
|
|
228
|
-
>
|
|
229
|
-
>
|
|
227
|
+
> **Fixed since 0.3.1.** `createAccess` used to throw when `fetchRules` was not a function,
|
|
228
|
+
> which on a page meant throwing at import. It now denies everything and says why through
|
|
229
|
+
> `failed` and `reason` (test "a missing fetcher denies everything instead of throwing").
|
|
230
|
+
> Building it inside `onReady` with an arrow is still the right shape.
|
|
231
|
+
|
|
232
|
+
## Roles and grants as data (0.6.0)
|
|
233
|
+
|
|
234
|
+
Wix member roles cannot be created or assigned from an installed app (WIXA-024), and a
|
|
235
|
+
business with several venues needs "Front desk at this venue" and "Manager of this vendor",
|
|
236
|
+
not one site-wide role. So 0.6.0 lets a policy declare a **permission catalogue**, and roles
|
|
237
|
+
and grants become **rows in your own collections**. The package never reads them: your hooks
|
|
238
|
+
hand them over, the package checks them, compiles them into ordinary rules, and refuses any
|
|
239
|
+
role or grant write that would hand out more than the writer holds.
|
|
240
|
+
|
|
241
|
+
A policy without `catalogue` behaves exactly as 0.5.2.
|
|
242
|
+
|
|
243
|
+
**The catalogue** — in the policy, validated at import:
|
|
244
|
+
|
|
245
|
+
```js
|
|
246
|
+
catalogue: {
|
|
247
|
+
scopes: ['business', 'vendor', 'venue'], // outermost first; 'site' is implicit
|
|
248
|
+
roleOwner: 'business', // who may own roles (scopes[0])
|
|
249
|
+
gates: { roles: 'roles.manage', grants: 'staff.manage' },
|
|
250
|
+
subjects: { admin: '*' }, // Wix-role subjects that count site-wide
|
|
251
|
+
store: { roles: 'StaffRoles', grants: 'StaffGrants' },
|
|
252
|
+
permissions: {
|
|
253
|
+
'bookings.work': { rules: [
|
|
254
|
+
// reads: one field, so every grant merges into one $in
|
|
255
|
+
{ actions: 'read', resource: 'Booking', scope: { location: 'venue' } },
|
|
256
|
+
// writes: also pin the collection's tenant, so a write cannot move the row away
|
|
257
|
+
{ actions: 'cancel', resource: 'Booking', scope: { location: 'venue', vendor: { kind: 'vendor', upward: true } } }
|
|
258
|
+
] },
|
|
259
|
+
'roles.manage': { rules: [
|
|
260
|
+
{ actions: ['read', 'create', 'update', 'delete'], resource: 'StaffRole', scope: { owner: 'business' } },
|
|
261
|
+
{ actions: 'read', resource: 'StaffRole', scope: 'any', where: { owner: null } }
|
|
262
|
+
] },
|
|
263
|
+
'staff.manage': { rules: [
|
|
264
|
+
{ actions: ['read', 'create', 'update', 'delete'], resource: 'StaffGrant', where: { scopeKind: 'venue' }, scope: { scopeId: 'venue' } }
|
|
265
|
+
] }
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
A rule's `scope` says which grants reach a row: `{ location: 'venue' }` is "the row's
|
|
271
|
+
`location` is one of the venues the grant reaches"; `{ kind, upward: true }` also admits the
|
|
272
|
+
grant's own ancestor of that kind. The validator refuses `manage`, `resource: 'all'`,
|
|
273
|
+
`scope: 'any'` on anything but `read`, an upward-only scope, and **a write rule that does not
|
|
274
|
+
pin its collection's `tenant` field**. Pin every field your hierarchy is built from, not only
|
|
275
|
+
the tenant: a venue editor whose rule pins only `_id` can set the venue's `vendor` to someone
|
|
276
|
+
else's. Store collections may not declare `owner` or `actor` (the gateway would stamp the
|
|
277
|
+
writer's id into the grant), and each gate's rules must name its store collection's resource.
|
|
278
|
+
|
|
279
|
+
**Rows.** A role: `{ _id, name, permissions: [...], owner: null | businessId, isArchived }` —
|
|
280
|
+
store `owner: null` explicitly for a site role. A grant: `{ memberId, email, role, scopeKind,
|
|
281
|
+
scopeId, status, isArchived }`, `scopeKind: 'site'` with `scopeId: null` for site-wide. Only a
|
|
282
|
+
grant whose `memberId` is the caller's counts: an email-only grant grants nothing until you
|
|
283
|
+
bind it (bind only to a member whose login email Wix reports as verified).
|
|
284
|
+
|
|
285
|
+
**The two hooks.**
|
|
286
|
+
|
|
287
|
+
```js
|
|
288
|
+
createAccess(policy, {
|
|
289
|
+
// Do the reads HERE, side by side with the ones you already make.
|
|
290
|
+
enrich: async (principal) => readCallerFacts(principal.memberId),
|
|
291
|
+
// A pure mapping of what enrich read: each grant with `covers` (ids it reaches per kind)
|
|
292
|
+
// and `path` (ids it sits under, itself included), plus the role rows they name.
|
|
293
|
+
// THROW when enrich could not read them, so the caller is UNVERIFIED, not "not allowed".
|
|
294
|
+
grants: (principal) => {
|
|
295
|
+
if (principal.domain.grantsUnverified) throw new Error('grant read failed')
|
|
296
|
+
return { roles: principal.domain.roleRows, grants: principal.domain.grantRows.map(expand) }
|
|
297
|
+
},
|
|
298
|
+
// Where a scope sits: { kind, id, path } or null. The same helper as `expand`.
|
|
299
|
+
scopeOf: async ({ kind, id }) => placeOf(kind, id)
|
|
300
|
+
})
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
grant at vendor v1 covers { vendor: [v1], venue: [l1, l2] } path { business: b, vendor: v1 }
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
The package adds no read of its own to a request; visitors never reach the hook. Grants it
|
|
308
|
+
cannot trust (another member's, archived, `status` not `ACTIVE`, a role missing, archived or
|
|
309
|
+
owned by another business, a path that contradicts the grant) are dropped and reported to
|
|
310
|
+
`audit` as `access.ignored`; an unknown permission is dropped from its role and reported, and
|
|
311
|
+
the rest of the role still applies. The compiled rules join the static ones in `rulesFor`, so
|
|
312
|
+
`guard`, `db` and page code use them unchanged, and they are computed once per principal.
|
|
313
|
+
|
|
314
|
+
**No escalation.** Every write to the store collections through `db` runs a pure check: the
|
|
315
|
+
writer must hold the gate (`roles.manage`, `staff.manage`) where the role or grant applies,
|
|
316
|
+
and every permission the role carries **there** — across the whole business for a business
|
|
317
|
+
role. Revoking is checked too: a manager cannot remove a grant whose role holds more than they
|
|
318
|
+
do. A refusal is `{ ok: false, code: 'FORBIDDEN', action: 'defineRole' | 'grantRole', detail:
|
|
319
|
+
{ reason, missing } }`, audited as `access.escalation`, and nothing is written. A grant write
|
|
320
|
+
reads its role and places its scope (one wave) after checking the row's shape; a read that
|
|
321
|
+
throws answers `UNVERIFIED`. `transfer` is refused on both collections.
|
|
322
|
+
|
|
323
|
+
Code that writes on the owner's authority (an import, an Apply) skips the escalation check
|
|
324
|
+
and runs the shape checks instead: `checkRoleRow(row, policy)` and
|
|
325
|
+
`checkGrantRow(row, policy, roles)` list every problem.
|
|
326
|
+
|
|
327
|
+
**Page code.** Serve `accessForCaller()` instead of `rulesForCaller()` and the page kit gains
|
|
328
|
+
`held()`, `holds(permission, scope?)`, `mayDefineRole(before, after)` and `mayGrant(input)` —
|
|
329
|
+
the server's own checks, over what was fetched. The page cannot place a scope by itself: pass
|
|
330
|
+
targets with their `path` (`grants.places` carries the caller's own; your screen's web method
|
|
331
|
+
sends the rest), or it refuses with `noPath`.
|
|
332
|
+
|
|
333
|
+
**Still not possible:** creating or assigning Wix member roles. Wix roles map to site-wide
|
|
334
|
+
grants through `catalogue.subjects`, matched by the role title the caller really holds.
|
|
230
335
|
|
|
231
336
|
## Things worth knowing
|
|
232
337
|
|
|
@@ -277,7 +382,7 @@ custom-role end-to-end flows are simply untested.
|
|
|
277
382
|
## Development
|
|
278
383
|
|
|
279
384
|
```bash
|
|
280
|
-
npm install && npm run verify # build both bundles, then
|
|
385
|
+
npm install && npm run verify # build both bundles, then 277 tests
|
|
281
386
|
```
|
|
282
387
|
|
|
283
388
|
`backend.js` and `public.js` are the two real bundles; `index.js` is a one-line
|
package/backend.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export * from './types'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Policy, Principal, Ability, SerialisedRule, Result, Clause, Scope,
|
|
4
|
+
GrantMaterial, Held, ScopeRef, RoleRow, GrantWrite, AccessForCaller, Ok, Denial
|
|
5
|
+
} from './types'
|
|
3
6
|
|
|
4
7
|
export type AuditEvent =
|
|
5
8
|
| {
|
|
@@ -30,6 +33,25 @@ export type AuditEvent =
|
|
|
30
33
|
collection: string
|
|
31
34
|
id: string
|
|
32
35
|
}
|
|
36
|
+
| {
|
|
37
|
+
/** 0.6.0: a grant the hook returned that does not count, and why. */
|
|
38
|
+
event: 'access.ignored'
|
|
39
|
+
reason: string
|
|
40
|
+
caller: string | null
|
|
41
|
+
grant: string | null
|
|
42
|
+
role: string | null
|
|
43
|
+
permission: string | null
|
|
44
|
+
}
|
|
45
|
+
| {
|
|
46
|
+
/** 0.6.0: a role or grant write refused by the no-escalation check. Nothing was written. */
|
|
47
|
+
event: 'access.escalation'
|
|
48
|
+
action: 'defineRole' | 'grantRole'
|
|
49
|
+
caller: string | null
|
|
50
|
+
collection: string
|
|
51
|
+
id: string | null
|
|
52
|
+
reason: string | null
|
|
53
|
+
missing: string[]
|
|
54
|
+
}
|
|
33
55
|
|
|
34
56
|
export interface CreateAccessOptions {
|
|
35
57
|
/** Adds domain facts to the Principal — vendor membership, tenancy, staff rows. */
|
|
@@ -44,6 +66,19 @@ export interface CreateAccessOptions {
|
|
|
44
66
|
* exact key still wins. Without it, a namespaced id matches only a namespaced key.
|
|
45
67
|
*/
|
|
46
68
|
namespace?: string
|
|
69
|
+
/**
|
|
70
|
+
* 0.6.0: the caller's grants, for a policy with a catalogue. Called once per request for a
|
|
71
|
+
* member (never a visitor, never an already unverified caller), after `enrich`. Make it a
|
|
72
|
+
* pure mapping of what `enrich` read, so it adds no wave of reads; THROW when that read
|
|
73
|
+
* failed, so the caller is UNVERIFIED rather than silently "not allowed".
|
|
74
|
+
*/
|
|
75
|
+
grants?: (principal: Principal) => Promise<GrantMaterial | null> | GrantMaterial | null
|
|
76
|
+
/**
|
|
77
|
+
* 0.6.0: where a scope sits — `{ kind, id, path }`, path holding it and every ancestor —
|
|
78
|
+
* or null when it does not exist. Required with `catalogue.store`: the gateway places each
|
|
79
|
+
* grant it is asked to write. Build it with the same helper as the `grants` hook.
|
|
80
|
+
*/
|
|
81
|
+
scopeOf?: (scope: { kind: string; id: string }) => Promise<ScopeRef | null>
|
|
47
82
|
/** Override the injected Wix modules. Tests only. */
|
|
48
83
|
deps?: Record<string, unknown>
|
|
49
84
|
}
|
|
@@ -124,8 +159,19 @@ export interface Access {
|
|
|
124
159
|
/** The permission level to type into your own webMethod() call. For tests. */
|
|
125
160
|
gateFor(name: string): string | null
|
|
126
161
|
db: Db
|
|
127
|
-
/** Hand these to page code from a web method. Plain JSON. */
|
|
162
|
+
/** Hand these to page code from a web method. Plain JSON. Includes compiled grant rules. */
|
|
128
163
|
rulesForCaller(): Promise<SerialisedRule[]>
|
|
164
|
+
/** 0.6.0: what this principal holds, and where. */
|
|
165
|
+
heldFor(principal: Principal): Held[]
|
|
166
|
+
/**
|
|
167
|
+
* 0.6.0: rules plus grants, plain JSON, for a page that edits roles or staff. `grants` is
|
|
168
|
+
* null without a catalogue; an unverified caller gets an UNVERIFIED envelope.
|
|
169
|
+
*/
|
|
170
|
+
accessForCaller(): Promise<AccessForCaller | Denial>
|
|
171
|
+
/** 0.6.0: the no-escalation check for a role write, bound to the policy. */
|
|
172
|
+
checkRoleWrite(principal: Principal, before: RoleRow | null, after: RoleRow | null): Ok<null> | Denial
|
|
173
|
+
/** 0.6.0: the no-escalation check for a grant write, bound to the policy. */
|
|
174
|
+
checkGrantWrite(principal: Principal, input: GrantWrite): Ok<null> | Denial
|
|
129
175
|
}
|
|
130
176
|
|
|
131
177
|
export declare function createAccess(policy: Policy, options?: CreateAccessOptions): Access
|
package/backend.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var sr=Object.create;var re=Object.defineProperty;var or=Object.getOwnPropertyDescriptor;var ir=Object.getOwnPropertyNames;var ar=Object.getPrototypeOf,cr=Object.prototype.hasOwnProperty;var ur=(t,e)=>{for(var r in e)re(t,r,{get:e[r],enumerable:!0})},mt=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of ir(e))!cr.call(t,s)&&s!==r&&re(t,s,{get:()=>e[s],enumerable:!(n=or(e,s))||n.enumerable});return t};var lr=(t,e,r)=>(r=t!=null?sr(ar(t)):{},mt(e||!t||!t.__esModule?re(r,"default",{value:t,enumerable:!0}):r,t)),fr=t=>mt(re({},"__esModule",{value:!0}),t);var dn={};ur(dn,{ASSIGN_OWNER:()=>$,CASES:()=>dt,CODES:()=>b,KIND:()=>P,PACKAGE_VERSION:()=>ft,PolicyError:()=>q,SCOPE:()=>S,WHEN:()=>U,abilityFor:()=>be,abilityFromRules:()=>at,anonymous:()=>gt,applyClauses:()=>Oe,applyGates:()=>Yt,assertDeclared:()=>Zt,assertGates:()=>zt,backendMemberId:()=>fn,backendPing:()=>ln,can:()=>A,caseTable:()=>Wt,createAccess:()=>un,createPrincipal:()=>K,deny:()=>N,denyOpaque:()=>M,filterFor:()=>ge,hasRole:()=>ne,isDenial:()=>bt,normaliseRoles:()=>xe,ok:()=>yt,parseGates:()=>ut,permissionFor:()=>wt,resolvePlaceholders:()=>Gt,resolveSubjects:()=>W,resolveWhere:()=>ye,rulesFor:()=>Y,validatePolicy:()=>se,verifyGates:()=>lt});module.exports=fr(dn);var pt=require("wix-members-backend"),er=lr(require("wix-users-backend"),1),tr=require("@wix/data"),rr=require("@wix/essentials");var b={FORBIDDEN:"FORBIDDEN",UNAUTHENTICATED:"UNAUTHENTICATED",UNVERIFIED:"UNVERIFIED",NOT_FOUND:"NOT_FOUND",INVALID_POLICY:"INVALID_POLICY",INVALID_ARGUMENT:"INVALID_ARGUMENT"},q=class extends Error{constructor(e){super(e),this.name="PolicyError",this.code=b.INVALID_POLICY}};function yt(t){return{ok:!0,data:t===void 0?null:t}}function N(t,e,r){let n={ok:!1,code:t||b.FORBIDDEN};return e&&(n.action=e),r&&(n.detail=r),n}var bt=t=>!!t&&t.ok===!1;function M(t){return N(b.NOT_FOUND,t)}var P={VISITOR:"visitor",MEMBER:"member",CAPABILITY:"capability",SERVICE:"service"};function xe(t){if(!Array.isArray(t))return[];let e=[];for(let r of t){if(typeof r=="string"){e.push(r);continue}if(!r||typeof r!="object")continue;let n=r.title||r.name||r.roleKey;n&&e.push(n)}return e}function K(t){let e=t||{},r=e.memberId||null,n=xe(e.roles);return{kind:e.kind||(r?P.MEMBER:P.VISITOR),memberId:r,roles:n,subjects:Array.isArray(e.subjects)?e.subjects.slice():[],domain:e.domain&&typeof e.domain=="object"?e.domain:{},unverified:!!e.unverified}}var gt=()=>K({kind:P.VISITOR}),ne=(t,e)=>t.roles.indexOf(e)!==-1;var U={ANYONE:"anyone",ANONYMOUS:"anonymous",MEMBER:"member"},_=t=>!!t&&typeof t=="object"&&!Array.isArray(t),dr=t=>Array.isArray(t)?t:[t];function g(t,e){throw new q("policy"+t+": "+e)}function pr(t,e){let r=".subjects."+t;_(e)||g(r,"must be an object");let s=["when","role","domain"].filter(o=>e[o]!==void 0);if(s.length===0&&g(r,'needs exactly one of when/role/domain \u2014 "{}" is ambiguous between a visitor and a member'),s.length>1&&g(r,"has "+s.join(" and ")+"; use exactly one"),e.when!==void 0){let o=[U.ANYONE,U.ANONYMOUS,U.MEMBER];o.indexOf(e.when)===-1&&g(r+".when","must be one of "+o.join(", ")+" (got "+JSON.stringify(e.when)+")")}e.role!==void 0&&typeof e.role!="string"&&g(r+".role","must be a string"),e.domain!==void 0&&typeof e.domain!="string"&&g(r+".domain","must be a string")}function hr(t,e,r){let n=".rules["+e+"]";_(t)||g(n,"must be an object"),typeof t.subject!="string"&&g(n+".subject","must be a string"),r.indexOf(t.subject)===-1&&g(n+".subject",'"'+t.subject+'" is not declared in policy.subjects'),t.actions===void 0&&g(n+".actions","is required");for(let s of dr(t.actions))typeof s!="string"&&g(n+".actions","must be a string or an array of strings");typeof t.resource!="string"&&g(n+".resource","must be a string"),t.where!==void 0&&!_(t.where)&&g(n+".where","must be an object")}var Ot=["Anyone","SiteMember","Admin"];function mr(t,e,r){let n=".api."+t;_(e)||g(n,"must be an object"),Ot.indexOf(e.permission)===-1&&g(n+".permission","must be one of "+Ot.join(", ")+" (got "+JSON.stringify(e.permission)+")"),e.ability!==void 0&&((!Array.isArray(e.ability)||e.ability.length!==2)&&g(n+".ability","must be [action, resource]"),(typeof e.ability[0]!="string"||typeof e.ability[1]!="string")&&g(n+".ability","both entries must be strings")),e.subject!==void 0&&r.indexOf(e.subject)===-1&&g(n+".subject",'"'+e.subject+'" is not declared in policy.subjects')}var yr=["resource","owner","actor","tenant","profile"];function br(t,e){let r=".collections."+t;_(e)||g(r,"must be an object");for(let n of yr)e[n]!==void 0&&(typeof e[n]!="string"||!e[n])&&g(r+"."+n,"must be a non-empty string");e.owner!==void 0&&e.owner===e.actor&&g(r,'owner and actor must be different fields (both are "'+e.owner+'")')}function se(t){if(!_(t))throw new q("policy must be an object");_(t.subjects)||g(".subjects","is required and must be an object");let e=Object.keys(t.subjects);e.length===0&&g(".subjects","declares no subjects");for(let r of e)pr(r,t.subjects[r]);if(Array.isArray(t.rules)||g(".rules","is required and must be an array"),t.rules.forEach((r,n)=>hr(r,n,e)),t.api!==void 0){_(t.api)||g(".api","must be an object");for(let r of Object.keys(t.api))mr(r,t.api[r],e)}if(t.collections!==void 0){_(t.collections)||g(".collections","must be an object");for(let r of Object.keys(t.collections))br(r,t.collections[r])}return t}function W(t,e){let r=new Set(t.subjects||[]);for(let n of Object.keys(e.subjects)){let s=e.subjects[n];(s.when===U.ANYONE||s.when===U.ANONYMOUS&&!t.memberId||s.when===U.MEMBER&&t.memberId||s.role!==void 0&&t.roles.indexOf(s.role)!==-1||s.domain!==void 0&&t.domain[s.domain])&&r.add(n)}return Array.from(r)}function wt(t,e){let r=t.api&&t.api[e];return r?r.permission:null}var oe=class{constructor(e,r){this.operator=e,this.value=r,Object.defineProperty(this,"t",{writable:!0})}get notes(){return this.t}addNote(e){this.t=this.t||[],this.t.push(e)}},Z=class extends oe{},G=class extends Z{constructor(e,r){if(!Array.isArray(r))throw new Error(`"${e}" operator expects to receive an array of conditions`);super(e,r)}},B="__itself__",V=class extends oe{constructor(e,r,n){super(e,n),this.field=r}},Ee=new Z("__null__",null),Ae=Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);function gr(t,e){return e instanceof G&&e.operator===t}function $e(t,e){return e.length===1?e[0]:new G(t,(function r(n,s,o){let i=o||[];for(let c=0,l=s.length;c<l;c++){let u=s[c];gr(n,u)?r(n,u.value,i):i.push(u)}return i})(t,e))}var Or=t=>t,xt=()=>Object.create(null),vt=Object.defineProperty(xt(),"__@type@__",{value:"ignore value"});function wr(t,e,r=!1){if(!t||t&&t.constructor!==Object)return!1;for(let n in t)if(Ae(t,n)&&Ae(e,n)&&(!r||t[n]!==vt))return!0;return!1}function xr(t){let e=[];for(let r in t)Ae(t,r)&&t[r]!==vt&&e.push(r);return e}function ve(t,e){e!==Ee&&t.push(e)}var Ie=t=>$e("and",t);var ie={compound(t,e,r){let n=(Array.isArray(e)?e:[e]).map(s=>r.parse(s));return new G(t.name,n)},field:(t,e,r)=>new V(t.name,r.field,e),document:(t,e)=>new Z(t.name,e)},H=class{constructor(e,r=xt()){this.o=void 0,this.s=void 0,this.i=void 0,this.u=void 0,this.h=void 0,this.parse=this.parse.bind(this),this.u={operatorToConditionName:r.operatorToConditionName||Or,defaultOperatorName:r.defaultOperatorName||"eq",mergeFinalConditions:r.mergeFinalConditions||Ie},this.o=Object.keys(e).reduce((n,s)=>(n[s]=Object.assign({name:this.u.operatorToConditionName(s)},e[s]),n),{}),this.s=Object.assign({},r.fieldContext,{field:"",query:{},parse:this.parse,hasOperators:n=>wr(n,this.o,r.useIgnoreValue)}),this.i=Object.assign({},r.documentContext,{parse:this.parse,query:{}}),this.h=r.useIgnoreValue?xr:Object.keys}setParse(e){this.parse=e,this.s.parse=e,this.i.parse=e}parseField(e,r,n,s){let o=this.o[r];if(!o)throw new Error(`Unsupported operator "${r}"`);if(o.type!=="field")throw new Error(`Unexpected ${o.type} operator "${r}" at field level`);return this.s.field=e,this.s.query=s,this.parseInstruction(o,n,this.s)}parseInstruction(e,r,n){return typeof e.validate=="function"&&e.validate(e,r),(e.parse||ie[e.type])(e,r,n)}parseFieldOperators(e,r){let n=[],s=this.h(r);for(let o=0,i=s.length;o<i;o++){let c=s[o];if(!this.o[c])throw new Error(`Field query for "${e}" may contain only operators or a plain object as a value`);ve(n,this.parseField(e,c,r[c],r))}return n}parse(e){let r=[],n=this.h(e);this.i.query=e;for(let s=0,o=n.length;s<o;s++){let i=n[s],c=e[i],l=this.o[i];if(l){if(l.type!=="document"&&l.type!=="compound")throw new Error(`Cannot use parsing instruction for operator "${i}" in "document" context as it is supposed to be used in "${l.type}" context`);ve(r,this.parseInstruction(l,c,this.i))}else this.s.hasOperators(c)?r.push(...this.parseFieldOperators(i,c)):ve(r,this.parseField(i,this.u.defaultOperatorName,c,e))}return this.u.mergeFinalConditions(r)}};function je(t,e){let r=t[e];if(typeof r!="function")throw new Error(`Unable to interpret "${e}" condition. Did you forget to register interpreter for it?`);return r}function vr(t){return t.operator}function jt(t,e){let r=e,n=r&&r.getInterpreterName||vr,s;switch(r?r.numberOfArguments:0){case 1:s=i=>{let c=n(i,r);return je(t,c)(i,o)};break;case 3:s=(i,c,l)=>{let u=n(i,r);return je(t,u)(i,c,l,o)};break;default:s=(i,c)=>{let l=n(i,r);return je(t,l)(i,c,o)}}let o=Object.assign({},r,{interpret:s});return o.interpret}function At(t,e){return(r,...n)=>{let s=t(r,...n),o=e.bind(null,s);return o.ast=s,o}}var wn=H.prototype.parseInstruction;function Et(t,e){if(!Array.isArray(e))throw new Error(`"${t.name}" expects value to be an array`)}function $t(t,e){if(Et(t,e),!e.length)throw new Error(`"${t.name}" expects to have at least one element in array`)}var Ne=t=>(e,r)=>{if(typeof r!==t)throw new Error(`"${e.name}" expects value to be a "${t}"`)},It={type:"compound",validate:$t,parse(t,e,{parse:r}){let n=e.map(s=>r(s));return $e(t.name,n)}},jr=It,Ar={type:"compound",validate:$t},Er={type:"field",validate(t,e){if(!(e&&(e instanceof RegExp||e.constructor===Object)))throw new Error(`"${t.name}" expects to receive either regular expression or object of field operators`)},parse(t,e,r){let n=e instanceof RegExp?new V("regex",r.field,e):r.parse(e,r);return new G(t.name,[n])}},Fe={type:"field",validate(t,e){if(!e||e.constructor!==Object)throw new Error(`"${t.name}" expects to receive an object with nested query or field level operators`)},parse(t,e,{parse:r,field:n,hasOperators:s}){let o=s(e)?r(e,{field:B}):r(e);return new V(t.name,n,o)}},Me={type:"field",validate:Ne("number")},Q={type:"field",validate:Et},Ce=Q,Se=Q,$r={type:"field",validate(t,e){if(!Array.isArray(e)||e.length!==2)throw new Error(`"${t.name}" expects an array with 2 numeric elements`)}},De={type:"field",validate:Ne("boolean")},ce={type:"field",validate:function(t,e){if(!(typeof e=="string"||typeof e=="number"||e instanceof Date))throw new Error(`"${t.name}" expects value to be comparable (i.e., string, number or date)`)}},X=ce,Re=X,_e=X,ue={type:"field"},ke=ue,Te={type:"field",validate(t,e){if(!(e instanceof RegExp)&&typeof e!="string")throw new Error(`"${t.name}" expects value to be a regular expression or a string that represents regular expression`)},parse(t,e,r){let n=typeof e=="string"?new RegExp(e,r.query.$options||""):e;return new V(t.name,r.field,n)}},Pe={type:"field",parse:()=>Ee},Ir={type:"document",validate:Ne("function")},Nr=Object.freeze({__proto__:null,$and:It,$or:jr,$nor:Ar,$not:Er,$elemMatch:Fe,$size:Me,$in:Q,$nin:Ce,$all:Se,$mod:$r,$exists:De,$gte:ce,$gt:X,$lt:Re,$lte:_e,$eq:ue,$ne:ke,$regex:Te,$options:Pe,$where:Ir}),ae=class extends H{constructor(e){super(e,{defaultOperatorName:"$eq",operatorToConditionName:r=>r.slice(1)})}parse(e,r){return r&&r.field?Ie(this.parseFieldOperators(r.field,e)):super.parse(e)}},le=Nr;function Ue(t,e,r){for(let n=0,s=t.length;n<s;n++)if(r(t[n],e)===0)return!0;return!1}function Be(t,e){return Array.isArray(t)&&Number.isNaN(Number(e))}function Nt(t,e,r){if(!Be(t,e))return r(t,e);let n=[];for(let s=0;s<t.length;s++){let o=r(t[s],e);o!==void 0&&(n=n.concat(o))}return n}function z(t){return(e,r,n)=>{let s=n.get(r,e.field);return Array.isArray(s)?s.some(o=>t(e,o,n)):t(e,s,n)}}var Fr=Object.hasOwn||Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty),Mr=(t,e)=>t[e];function Ft(t,e,r){let n=e.lastIndexOf(".");return n===-1?[t,e]:[r(t,e.slice(0,n)),e.slice(n+1)]}function Cr(t,e,r=Mr){if(e===B)return t;if(!t)throw new Error(`Unable to get field "${e}" out of ${String(t)}.`);return(function(n,s,o){if(s.indexOf(".")===-1)return Nt(n,s,o);let i=s.split("."),c=n;for(let l=0,u=i.length;l<u;l++)if(c=Nt(c,i[l],o),!c||typeof c!="object")return l<u-1?void 0:c;return c})(t,e,r)}function Le(t,e){return t===e?0:t>e?1:-1}function qe(t,e={}){return jt(t,Object.assign({get:Cr,compare:Le},e))}var Mt=(t,e,{interpret:r})=>t.value.some(n=>r(n,e)),Sr=(t,e,r)=>!Mt(t,e,r),Ge=(t,e,{interpret:r})=>t.value.every(n=>r(n,e)),Dr=(t,e,{interpret:r})=>!r(t.value[0],e),fe=(t,e,{compare:r,get:n})=>{let s=n(e,t.field);return Array.isArray(s)&&!Array.isArray(t.value)?Ue(s,t.value,r):r(s,t.value)===0},Ve=(t,e,r)=>!fe(t,e,r),ze=z((t,e,r)=>{let n=r.compare(e,t.value);return n===0||n===-1}),Ye=z((t,e,r)=>r.compare(e,t.value)===-1),We=z((t,e,r)=>r.compare(e,t.value)===1),Je=z((t,e,r)=>{let n=r.compare(e,t.value);return n===0||n===1}),Ke=(t,e,{get:r})=>{if(t.field===B)return e!==void 0;let[n,s]=Ft(e,t.field,r),o=i=>i==null?!!i===t.value:Fr(i,s)===t.value;return Be(n,s)?n.some(o):o(n)},Rr=z((t,e)=>typeof e=="number"&&e%t.value[0]===t.value[1]),Ze=(t,e,{get:r})=>{let[n,s]=Ft(e,t.field,r),o=i=>{let c=r(i,s);return Array.isArray(c)&&c.length===t.value};return t.field!==B&&Be(n,s)?n.some(o):o(n)},He=z((t,e)=>typeof e=="string"&&t.value.test(e)),ee=z((t,e,{compare:r})=>Ue(t.value,e,r)),Qe=(t,e,r)=>!ee(t,e,r),Xe=(t,e,{compare:r,get:n})=>{let s=n(e,t.field);return Array.isArray(s)&&t.value.every(o=>Ue(s,o,r))},et=(t,e,{interpret:r,get:n})=>{let s=n(e,t.field);return Array.isArray(s)&&s.some(o=>r(t.value,o))},_r=(t,e)=>t.value.call(e),kr=Object.freeze({__proto__:null,or:Mt,nor:Sr,and:Ge,not:Dr,eq:fe,ne:Ve,lte:ze,lt:Ye,gt:We,gte:Je,exists:Ke,mod:Rr,size:Ze,regex:He,within:ee,nin:Qe,all:Xe,elemMatch:et,where:_r}),de=Object.assign({},kr,{in:ee}),$n=qe(de);function Ct(t){return t===null||typeof t!="object"?t:t instanceof Date?t.getTime():t&&typeof t.toJSON=="function"?t.toJSON():t}var Tr=(t,e)=>Le(Ct(t),Ct(e));function pe(t,e,r){let n=new ae(t),s=qe(e,Object.assign({compare:Tr},r));if(r&&r.forPrimitives){let o={field:B},i=n.parse;n.setParse(c=>i(c,o))}return At(n.parse,s)}var Cn=pe(le,de),Sn=pe(["$and","$or"].reduce((t,e)=>(t[e]=Object.assign({},t[e],{type:"field"}),t),Object.assign({},le,{$nor:Object.assign({},le.$nor,{type:"field",parse:ie.compound})})),de,{forPrimitives:!0});var Tt=Object.hasOwn||((t,e)=>Object.prototype.hasOwnProperty.call(t,e));function tt(t){return Array.isArray(t)?t:[t]}var J="__caslSubjectType__";function Pt(t,e){if(e){if(!Tt(e,J))Object.defineProperty(e,J,{value:t});else if(t!==e[J])throw new Error(`Trying to cast object to subject type ${t} but previously it was casted to ${e[J]}`)}return e}var me=t=>{let e=typeof t;return e==="string"||e==="function"},Ut=t=>t.modelName||t.name;function Pr(t){return typeof t=="string"?t:Ut(t)}function Bt(t){return Tt(t,J)?t[J]:Ut(t.constructor)}var St={function:t=>t.constructor,string:Bt};function Dt(t,e,r){for(let n=r;n<e.length;n++)t.push(e[n])}function Rt(t,e){if(!t||!t.length)return e||[];if(!e||!e.length)return t||[];let r=0,n=0,s=[];for(;r<t.length&&n<e.length;)t[r].priority<e[n].priority?(s.push(t[r]),r++):t[r].priority>e[n].priority?(s.push(e[n]),n++):(s.push(t[r]),r++,n++);return Dt(s,t,r),Dt(s,e,n),s}function he(t,e,r){let n=t.get(e);return n||(n=r(),t.set(e,n)),n}var Ur=t=>t;function Br(t,e){let r;for(let n=0;n<t.length;n++){let s=e(t[n]);r&&s&&r.push(t[n]),s||(r??=t.slice(0,n))}return r||t}function Lr(t,e){if(Array.isArray(t.fields)&&!t.fields.length)throw new Error("`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa");if(t.fields&&!e.fieldMatcher)throw new Error('You need to pass "fieldMatcher" option in order to restrict access by fields');if(t.conditions&&!e.conditionsMatcher)throw new Error('You need to pass "conditionsMatcher" option in order to restrict access by conditions')}var rt=class{constructor(e,r,n=0){Lr(e,r),this.action=r.resolveAction(e.action),this.subject=e.subject,this.inverted=!!e.inverted,this.conditions=e.conditions,this.reason=e.reason,this.origin=e,this.fields=e.fields?tt(e.fields):void 0,this.priority=n,this.t=r}i(){return this.conditions&&!this.o&&(this.o=this.t.conditionsMatcher(this.conditions)),this.o}get ast(){let e=this.i();return e?e.ast:void 0}matchesConditions(e){return this.conditions?!e||me(e)?!this.inverted:this.i()(e):!0}matchesField(e){return this.fields?e?(this.u||(this.u=this.t.fieldMatcher(this.fields)),this.u(e)):!this.inverted:!0}};function qr(t,e){let r={value:t,prev:e,next:null};return e&&(e.next=r),r}function Gr(t){t.next&&(t.next.prev=t.prev),t.prev&&(t.prev.next=t.next),t.next=t.prev=null}var _t=()=>({rules:[],merged:!1}),kt=()=>new Map,nt=class{constructor(e=[],r={}){this.h=!1,this.l=new Map,this.p={conditionsMatcher:r.conditionsMatcher,fieldMatcher:r.fieldMatcher,resolveAction:r.resolveAction||Ur},this.$=r.anyAction||"manage",this.A=r.anySubjectType||"all",this.m=e,this.M=!!r.detectSubjectType,this.j=r.detectSubjectType||Bt,this.v(e)}get rules(){return this.m}detectSubjectType(e){return me(e)?e:e?this.j(e):this.A}update(e){let r={rules:e,ability:this,target:this};return this._("update",r),this.m=e,this.v(e),this._("updated",r),this}v(e){let r=new Map,n;for(let s=e.length-1;s>=0;s--){let o=e.length-s-1,i=new rt(e[s],this.p,o),c=tt(i.action),l=tt(i.subject||this.A);!this.h&&i.fields&&(this.h=!0);for(let u=0;u<l.length;u++){let O=he(r,l[u],kt);n===void 0&&(n=typeof l[u]),typeof l[u]!==n&&n!=="mixed"&&(n="mixed");for(let E=0;E<c.length;E++)he(O,c[E],_t).rules.push(i)}}if(this.l=r,n!=="mixed"&&!this.M){let s=St[n]||St.string;this.j=s}}possibleRulesFor(e,r=this.A){if(!me(r))throw new Error('"possibleRulesFor" accepts only subject types (i.e., string or class) as the 2nd parameter');let n=he(this.l,r,kt),s=he(n,e,_t);if(s.merged)return s.rules;let o=e!==this.$&&n.has(this.$)?n.get(this.$).rules:void 0,i=Rt(s.rules,o);return r!==this.A&&(i=Rt(i,this.possibleRulesFor(e,this.A))),s.rules=i,s.merged=!0,i}rulesFor(e,r,n){let s=this.possibleRulesFor(e,r);if(n&&typeof n!="string")throw new Error("The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details");return this.h?Br(s,o=>o.matchesField(n)):s}actionsFor(e){if(!me(e))throw new Error('"actionsFor" accepts only subject types (i.e., string or class) as a parameter');let r=new Set,n=this.l.get(e);n&&Array.from(n.keys()).forEach(o=>r.add(o));let s=e!==this.A?this.l.get(this.A):void 0;return s&&Array.from(s.keys()).forEach(o=>r.add(o)),Array.from(r)}on(e,r){this.F=this.F||new Map;let n=this.F,s=n.get(e)||null,o=qr(r,s);return n.set(e,o),()=>{let i=n.get(e);!o.next&&!o.prev&&i===o?n.delete(e):o===i&&n.set(e,o.prev),Gr(o)}}_(e,r){if(!this.F)return;let n=this.F.get(e)||null,s=[];for(;n!==null;)s.push(n.value),n=n.prev;for(let o=0;o<s.length;o++)s[o](r)}},st=class extends nt{can(e,r,n){let s=this.relevantRuleFor(e,r,n);return!!s&&!s.inverted}relevantRuleFor(e,r,n){let s=this.detectSubjectType(r),o=this.rulesFor(e,s,n);for(let i=0,c=o.length;i<c;i++)if(o[i].matchesConditions(r))return o[i];return null}cannot(e,r,n){return!this.can(e,r,n)}},Vr={$eq:ue,$ne:ke,$lt:Re,$lte:_e,$gt:X,$gte:ce,$in:Q,$nin:Ce,$all:Se,$size:Me,$regex:Te,$options:Pe,$elemMatch:Fe,$exists:De},zr={eq:fe,ne:Ve,lt:Ye,lte:ze,gt:We,gte:Je,in:ee,nin:Qe,all:Xe,size:Ze,regex:He,elemMatch:et,exists:Ke,and:Ge};var Yr=pe(Vr,zr),Wr=/[-/\\^$+?.()|[\]{}]/g,Jr=/\.?\*+\.?/g,Kr=/\*+/,Zr=/\./g;function Hr(t,e,r){let n=r[0]==="*"||t[0]==="."&&t[t.length-1]==="."?"+":"*",s=t.indexOf("**")===-1?"[^.]":".",o=t.replace(Zr,"\\$&").replace(Kr,s+n);return e+t.length===r.length?`(?:${o})?`:o}function Qr(t,e,r){return t==="."&&(r[e-1]==="*"||r[e+1]==="*")?t:`\\${t}`}function Xr(t){let e=t.map(n=>n.replace(Wr,Qr).replace(Jr,Hr)),r=e.length>1?`(?:${e.join("|")})`:e[0];return new RegExp(`^${r}$`)}var en=t=>{let e;return r=>(typeof e>"u"&&(e=t.every(n=>n.indexOf("*")===-1)?null:Xr(t)),e===null?t.indexOf(r)!==-1:e.test(r))};function Lt(t=[],e={}){return new st(t,Object.assign({conditionsMatcher:Yr,fieldMatcher:en},e))}var tn=t=>`Cannot execute "${t.action}" on "${t.subjectType}"`,qt=function(e){this.message=e};qt.prototype=Object.create(Error.prototype);var ot=class extends qt{static setDefaultMessage(e){this.P=typeof e=="string"?()=>e:e}static from(e){return new this(e)}constructor(e){super(""),this.ability=e,typeof Error.captureStackTrace=="function"&&(this.name="ForbiddenError",Error.captureStackTrace(this,this.constructor))}setMessage(e){return this.message=e,this}throwUnlessCan(e,r,n){let s=this.unlessCan(e,r,n);if(s)throw s}unlessCan(e,r,n){let s=this.ability.relevantRuleFor(e,r,n);if(s&&!s.inverted)return;this.action=e,this.subject=r,this.subjectType=Pr(this.ability.detectSubjectType(r)),this.field=n;let o=s?s.reason:"";return this.message=this.message||o||this.constructor.P(this),this}};ot.P=tn;var Pn=Object.freeze({__proto__:null});function it(t,e,r){if(t==null)return t;if(typeof t=="string"){if(t.indexOf("$principal.")!==0)return t;let s=t.slice(11).split(".").reduce((o,i)=>o==null?o:o[i],e);return s==null&&(r.unresolved=!0),s}if(Array.isArray(t))return t.map(n=>it(n,e,r));if(typeof t=="object"){let n={};for(let s of Object.keys(t))n[s]=it(t[s],e,r);return n}return t}function ye(t,e){let r={unresolved:!1};return{conditions:it(t,e,r),unresolved:r.unresolved}}function Gt(t,e){return ye(t,e).conditions}function Y(t,e){let r=W(t,e),n=[];for(let s of e.rules){if(r.indexOf(s.subject)===-1)continue;let o={action:s.actions,subject:s.resource};if(s.where){let{conditions:i,unresolved:c}=ye(s.where,t);if(c)continue;o.conditions=i}n.push(o)}return n}function at(t){return Lt(Array.isArray(t)?t:[])}function be(t,e){return at(Y(t,e))}function A(t,e,r,n){return n==null?t.can(e,r):t.can(e,Pt(r,Object.assign({},n)))}var S={ALL:"all",NONE:"none",FIELDS:"fields",AMBIGUOUS:"ambiguous"},Vt={$in:"in",$nin:"nin",$ne:"ne",$gt:"gt",$gte:"gte",$lt:"lt",$lte:"lte"};function rn(t){let e=[];for(let r of Object.keys(t)){let n=t[r];if(n===null||typeof n!="object"||Array.isArray(n)){e.push({field:r,op:"eq",value:n});continue}let s=Object.keys(n);if(s.length!==1||!Vt[s[0]])return null;e.push({field:r,op:Vt[s[0]],value:n[s[0]]})}return e}var nn=(t,e)=>t==="manage"||t===e||Array.isArray(t)&&(t.indexOf(e)!==-1||t.indexOf("manage")!==-1),sn=(t,e)=>t==="all"||t===e;function ge(t,e,r,n){let s=Y(t,e).filter(i=>nn(i.action,r)&&sn(i.subject,n));if(s.length===0)return{scope:S.NONE,clauses:[]};if(s.some(i=>!i.conditions))return{scope:S.ALL,clauses:[]};if(s.length>1)return{scope:S.AMBIGUOUS,clauses:[]};let o=rn(s[0].conditions);return o?{scope:S.FIELDS,clauses:o}:{scope:S.AMBIGUOUS,clauses:[]}}function Oe(t,e){let r=t;for(let n of e)n.op==="in"?r=r.hasSome(n.field,n.value):n.op==="nin"?r=r.not(r.hasSome(n.field,n.value)):r=r[n.op](n.field,n.value);return r}var ct=/export\s+const\s+([A-Za-z0-9_$]+)\s*=\s*webMethod\s*\(\s*Permissions\s*\.\s*([A-Za-z0-9_$]+)/g,on=[[/export\s*{\s*[A-Za-z0-9_$,\s]+}/,"export { x } \u2014 the call and the export must be one statement"],[/export\s+const\s+[A-Za-z0-9_$]+\s*=\s*webMethod\s*\(\s*Permissions\s*\[/,"Permissions['X'] \u2014 the property must be dotted and literal"],[/export\s+const\s+[A-Za-z0-9_$]+\s*=\s*webMethod\s*\(\s*[A-Za-z0-9_$]+\s*\(/,"a computed permission \u2014 it must be written out as Permissions.LEVEL"]];function ut(t){let e={},r=String(t||"");ct.lastIndex=0;let n=ct.exec(r);for(;n;)e[n[1]]=n[2],n=ct.exec(r);return e}function lt(t,e,r){let n=r||{},s=e&&e.api||{},o=ut(t),i=String(t||""),c=[],l=[];for(let y of Object.keys(o)){let C=s[y];C?C.permission!==o[y]&&c.push({name:y,declared:C.permission,written:o[y]}):l.push({name:y,gate:o[y]})}let u=n.complete?Object.keys(s).filter(y=>!(y in o)):[],O=[];for(let[y,C]of on)y.test(i)&&O.push(C);return{ok:c.length+l.length+u.length+O.length===0,found:o,mismatched:c,undeclared:l,missing:u,suspect:O}}function zt(t,e,r){let n=lt(t,e,r);if(n.ok)return!0;let s=[];for(let o of n.mismatched)s.push(o.name+": policy says "+o.declared+", the export says "+o.written);for(let o of n.undeclared)s.push(o.name+": gated "+o.gate+" but missing from policy.api");for(let o of n.missing)s.push(o+": declared in policy.api but not exported here");for(let o of n.suspect)s.push("unreachable export shape \u2014 "+o);throw new Error(`wix-access: web-method gates do not match the policy:
|
|
2
|
-
`+
|
|
3
|
-
`))}function Yt(t,e){let r=e&&e.api||{},n=t||{},s={},o=[];for(let i of Object.keys(n)){let c=n[i],l=r[i];if(!l){o.push(i);continue}if(typeof c!="function"){o.push(i+" (not a function: "+typeof c+")");continue}try{c.permission=l.permission,s[i]=l.permission}catch(u){o.push(i+" (could not stamp: "+String(u&&u.message)+")")}}if(o.length)throw new Error("wix-access: applyGates could not gate: "+o.join(", ")+". Every exported web method must be declared in policy.api.");return s}var ft="0.5.2";var dt=[{action:"read",type:"Booking",object:{customerId:"m-1"}},{action:"read",type:"Booking",object:{customerId:"m-2"}},{action:"cancel",type:"Booking",object:{customerId:"m-1"}},{action:"delete",type:"Booking",object:{customerId:"m-1"}},{action:"manage",type:"Vendor",object:{_id:"v-1"}}];function Wt(t){return dt.map(e=>({action:e.action,type:e.type,object:e.object,can:A(t,e.action,e.type,e.object)}))}function Jt(t,e){let{wixUsers:r,currentMember:n}=t,s=e&&e.enrich||null,o=e&&e.onError||null;return async function(){let c=null,l=!1,u=!1;try{c=r.currentUser&&r.currentUser.id||null,l=!!(r.currentUser&&r.currentUser.loggedIn)}catch(y){u=!0,o&&o("resolveCaller.id",y)}let O=[];if(c)try{O=await n.getRoles()}catch(y){u=!0,o&&o("resolveCaller.roles",y)}let E=K({kind:c?P.MEMBER:P.VISITOR,memberId:c,roles:O,unverified:u});if(E.loggedIn=l,s)try{let y=await s(E);y&&typeof y=="object"&&(E.domain=y)}catch(y){E.unverified=!0,o&&o("resolveCaller.enrich",y)}return E}}var an="Admin";function Kt(t,e,r){let n=r.resolveCaller,s=r.abilityFor,o=r.audit||null;function i(l,u,O,E){return o&&o({event:"access.denied",action:l,code:u,caller:O?O.memberId:null,detail:E||null}),N(u,l)}function c(l,u,O){return u==="Anyone"?null:O.memberId?u==="Admin"&&!ne(O,an)?i(l,b.FORBIDDEN,O,{gate:u}):null:i(l,b.UNAUTHENTICATED,O)}return function(u,O,E){let y=t.api&&t.api[u]||null;if(!y)throw new Error('wix-access: web method "'+u+'" is not declared in policy.api. Add it, or the gate it runs behind is undocumented.');let C=E||{},k=y.permission,te=y.ability||null,a=C.strip||[];return async function(...f){let p=await n();if(p.unverified)return i(u,b.UNVERIFIED,p);let w=c(u,k,p);if(w)return w;let m=f.map(d=>{if(!d||typeof d!="object"||Array.isArray(d))return d;let x=Object.assign({},d);for(let v of a)delete x[v];return x}),h=null;if(te){let[d,x]=te;if(C.load){if(h=await C.load(...m),!h)return i(u,b.NOT_FOUND,p);if(!A(s(p),d,x,h))return M(u)}else if(!A(s(p),d,x))return i(u,b.FORBIDDEN,p)}return O({principal:p,subject:h},...m)}}}function Zt(t,e){let r=Object.keys(t&&t.api||{}),n=e.filter(s=>r.indexOf(s)===-1);if(n.length)throw new Error("wix-access: web methods missing from policy.api: "+n.join(", "));return!0}var Ht=100,cn=100,$="assignOwner";function Qt(t,e,r){let{items:n,auth:s}=e,o=r.abilityFor,i=r.audit||null,c=r.onError||null;function l(a){if(i)try{i(a)}catch(f){c&&c("audit",f)}}let u={query:(...a)=>s.elevate(n.query)(...a),get:(...a)=>s.elevate(n.get)(...a),insert:(...a)=>s.elevate(n.insert)(...a),update:(...a)=>s.elevate(n.update)(...a),remove:(...a)=>s.elevate(n.remove)(...a)},O=r.namespace||null,E=a=>{let f=t.collections||{};return f[a]?f[a]:O&&typeof a=="string"&&a.indexOf(O)===0&&f[a.slice(O.length)]||null},y=a=>{let f=E(a);return f&&f.owner?f.owner:null},C=a=>{let f=E(a);return f&&f.actor?f.actor:null},k=a=>{let f=E(a);return f&&f.resource||a};async function te(a,f){let p=[],w=await a.limit(Math.min(f||Ht,Ht)).find(),m=0;for(;w;){for(let h of w.items)p.push(h);if(f&&p.length>=f)return p.slice(0,f);if(!w.hasNext||!w.hasNext()||++m>=cn)break;w=await w.next()}return p}return{async query(a,f){let{principal:p,action:w="read",limit:m}=f,h=k(a),d=ge(p,t,w,h);if(d.scope===S.NONE)return{ok:!0,data:[],scope:d.scope};let x=u.query(a);d.scope===S.FIELDS&&(x=Oe(x,d.clauses));let v=await te(x,d.scope===S.AMBIGUOUS?null:m);if(d.scope!==S.AMBIGUOUS)return{ok:!0,data:v,scope:d.scope};let I=o(p),j=v.filter(F=>A(I,w,h,F));return{ok:!0,data:m?j.slice(0,m):j,scope:d.scope}},async get(a,f,p){let{principal:w,action:m="read"}=p,h=k(a),d=await u.get(a,f);return d?A(o(w),m,h,d)?{ok:!0,data:d}:M(m):M(m)},async insert(a,f,p){let{principal:w,action:m="create",onBehalfOf:h,system:d=!1}=p,x=k(a),v=y(a),I=C(a),j=w.memberId||null;if(h!==void 0){if(!v)return N(b.INVALID_ARGUMENT,m,{reason:a+" declares no owner field"});if(typeof h!="string"||!h)return N(b.INVALID_ARGUMENT,m,{reason:"onBehalfOf must be a member id"})}else if(d)return N(b.INVALID_ARGUMENT,m,{reason:"system is only meaningful with onBehalfOf"});let F=Object.assign({},f),R=h!==void 0?h:j,L=R!==j;v&&(F[v]=R),I&&(F[I]=j);let D=o(w);if(L&&!d&&!A(D,$,x,F))return l({event:"access.denied",action:$,code:b.FORBIDDEN,caller:j,detail:{collection:a,owner:R}}),N(b.FORBIDDEN,$);if(!A(D,m,x,F))return N(b.FORBIDDEN,m);let T=await u.insert(a,F);return L&&l({event:"access.onBehalf",action:m,caller:j,owner:R,system:d,collection:a,id:T&&T._id}),{ok:!0,data:T}},async update(a,f,p,w){let{principal:m,action:h="update",merge:d}=w;if(w.onBehalfOf!==void 0)return N(b.INVALID_ARGUMENT,h,{reason:"onBehalfOf is for insert; an update carries the new owner in its changes"});if(d!==void 0&&typeof d!="function")return N(b.INVALID_ARGUMENT,h,{reason:"merge must be a function (existing, changes) => row"});let x=k(a),v=await u.get(a,f);if(!v)return M(h);let I=o(m);if(!A(I,h,x,v))return M(h);let j=y(a),F=C(a),R=m.memberId||null,L=d?d(v,p):Object.assign({},v,p),D=Object.assign({},L,{_id:f});F&&(D[F]=v[F]);let T=null;if(j){let ht=v[j]===void 0?null:v[j],we=D[j]===void 0?null:D[j];we!==ht&&(A(I,$,x,v)&&A(I,$,x,D)?T={from:ht,to:we}:(D[j]=v[j],l({event:"access.denied",action:$,code:b.FORBIDDEN,caller:R,detail:{collection:a,id:f,owner:we}})))}if(!A(I,h,x,D))return N(b.FORBIDDEN,h);let nr=await u.update(a,D);return T&&l({event:"access.transfer",action:$,caller:R,from:T.from,owner:T.to,system:!1,collection:a,id:f}),{ok:!0,data:nr}},async transfer(a,f,p,w){let{principal:m,system:h=!1}=w,d=k(a),x=y(a),v=m.memberId||null;if(!x)return N(b.INVALID_ARGUMENT,$,{reason:a+" declares no owner field"});if(p!==null&&(typeof p!="string"||!p))return N(b.INVALID_ARGUMENT,$,{reason:"newOwner must be a member id or null"});let I=await u.get(a,f);if(!I)return M($);let j=Object.assign({},I,{_id:f,[x]:p});if(!h){let L=o(m);if(!A(L,$,d,I)||!A(L,$,d,j))return l({event:"access.denied",action:$,code:b.FORBIDDEN,caller:v,detail:{collection:a,id:f}}),M($)}let F=I[x]===void 0?null:I[x];if(F===p)return{ok:!0,data:I};let R=await u.update(a,j);return l({event:"access.transfer",action:$,caller:v,from:F,owner:p,system:h,collection:a,id:f}),{ok:!0,data:R}},async remove(a,f,p){let{principal:w,action:m="delete"}=p,h=k(a),d=await u.get(a,f);return d?A(o(w),m,h,d)?{ok:!0,data:await u.remove(a,f)}:M(m):M(m)}}}function Xt(t,e,r){se(t);let n=r||{};if(n.namespace!==void 0&&(typeof n.namespace!="string"||!n.namespace))throw new Error('wix-access: options.namespace must be a non-empty string, e.g. "@scope/app/"');let s=Jt(e,{enrich:n.enrich,onError:n.onError}),o=async()=>{let u=await s();return u.subjects=W(u,t),u},i=u=>be(u,t),c=Kt(t,e,{resolveCaller:o,abilityFor:i,audit:n.audit}),l=Qt(t,e,{abilityFor:i,audit:n.audit,onError:n.onError,namespace:n.namespace});return{policy:t,resolveCaller:o,abilityFor:i,guard:c,db:l,gateFor:u=>{let O=t.api&&t.api[u]||null;return O?O.permission:null},rulesForCaller:async()=>Y(await o(),t)}}function un(t,e){let r=e||{},n=Object.assign({wixUsers:er.default,currentMember:pt.currentMember,items:tr.items,auth:rr.auth},r.deps||{});return Xt(t,n,r)}function ln(){return{ok:!0,side:"backend",version:ft}}async function fn(){try{let t=await pt.currentMember.getMember();return t&&t._id||null}catch{return null}}0&&(module.exports={ASSIGN_OWNER,CASES,CODES,KIND,PACKAGE_VERSION,PolicyError,SCOPE,WHEN,abilityFor,abilityFromRules,anonymous,applyClauses,applyGates,assertDeclared,assertGates,backendMemberId,backendPing,can,caseTable,createAccess,createPrincipal,deny,denyOpaque,filterFor,hasRole,isDenial,normaliseRoles,ok,parseGates,permissionFor,resolvePlaceholders,resolveSubjects,resolveWhere,rulesFor,validatePolicy,verifyGates});
|
|
1
|
+
var Zn=Object.create;var Fe=Object.defineProperty;var Hn=Object.getOwnPropertyDescriptor;var Qn=Object.getOwnPropertyNames;var Xn=Object.getPrototypeOf,es=Object.prototype.hasOwnProperty;var ts=(e,t)=>{for(var n in t)Fe(e,n,{get:t[n],enumerable:!0})},tn=(e,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Qn(t))!es.call(e,r)&&r!==n&&Fe(e,r,{get:()=>t[r],enumerable:!(s=Hn(t,r))||s.enumerable});return e};var ns=(e,t,n)=>(n=e!=null?Zn(Xn(e)):{},tn(t||!e||!e.__esModule?Fe(n,"default",{value:e,enumerable:!0}):n,e)),ss=e=>tn(Fe({},"__esModule",{value:!0}),e);var gr={};ts(gr,{ASSIGN_OWNER:()=>G,CASES:()=>Xt,CODES:()=>m,KIND:()=>re,PACKAGE_VERSION:()=>Qt,PolicyError:()=>te,SCOPE:()=>W,SITE:()=>R,WHEN:()=>ie,abilityFor:()=>Ze,abilityFromRules:()=>Kt,anonymous:()=>sn,applyClauses:()=>Qe,applyGates:()=>Mn,assertDeclared:()=>Bn,assertGates:()=>_n,backendMemberId:()=>hr,backendPing:()=>mr,can:()=>T,caseTable:()=>Un,checkGrantRow:()=>Re,checkGrantWrite:()=>Ae,checkRoleRow:()=>Ht,checkRoleWrite:()=>we,contains:()=>Zt,createAccess:()=>pr,createPrincipal:()=>xe,deny:()=>A,denyOpaque:()=>Y,filterFor:()=>He,grantRulesFor:()=>Ye,hasRole:()=>Se,heldBy:()=>Xe,holdsAt:()=>Oe,isDenial:()=>nn,normaliseRoles:()=>st,ok:()=>ve,parseGates:()=>Wt,permissionFor:()=>an,resolveGrants:()=>Je,resolvePlaceholders:()=>Vt,resolveSubjects:()=>he,resolveWhere:()=>me,rulesFor:()=>ce,validateCatalogue:()=>_e,validatePolicy:()=>Me,verifyGates:()=>Jt});module.exports=ss(gr);var en=require("wix-members-backend"),zn=ns(require("wix-users-backend"),1),Wn=require("@wix/data"),Jn=require("@wix/essentials");var m={FORBIDDEN:"FORBIDDEN",UNAUTHENTICATED:"UNAUTHENTICATED",UNVERIFIED:"UNVERIFIED",NOT_FOUND:"NOT_FOUND",INVALID_POLICY:"INVALID_POLICY",INVALID_ARGUMENT:"INVALID_ARGUMENT"},te=class extends Error{constructor(t){super(t),this.name="PolicyError",this.code=m.INVALID_POLICY}};function ve(e){return{ok:!0,data:e===void 0?null:e}}function A(e,t,n){let s={ok:!1,code:e||m.FORBIDDEN};return t&&(s.action=t),n&&(s.detail=n),s}var nn=e=>!!e&&e.ok===!1;function Y(e){return A(m.NOT_FOUND,e)}var re={VISITOR:"visitor",MEMBER:"member",CAPABILITY:"capability",SERVICE:"service"};function st(e){if(!Array.isArray(e))return[];let t=[];for(let n of e){if(typeof n=="string"){t.push(n);continue}if(!n||typeof n!="object")continue;let s=n.title||n.name||n.roleKey;s&&t.push(s)}return t}function xe(e){let t=e||{},n=t.memberId||null,s=st(t.roles);return{kind:t.kind||(n?re.MEMBER:re.VISITOR),memberId:n,roles:s,subjects:Array.isArray(t.subjects)?t.subjects.slice():[],domain:t.domain&&typeof t.domain=="object"?t.domain:{},unverified:!!t.unverified,grants:Array.isArray(t.grants)?t.grants.slice():[]}}var sn=()=>xe({kind:re.VISITOR}),Se=(e,t)=>e.roles.indexOf(t)!==-1;var R="site",rs=/^[a-z][a-z0-9]*([._-][a-z0-9]+)*$/,os="read",H=e=>!!e&&typeof e=="object"&&!Array.isArray(e),is=e=>Array.isArray(e)?e:[e],De=(e,t)=>!!e&&Object.prototype.hasOwnProperty.call(e,t);function y(e,t){throw new te("policy.catalogue"+e+": "+t)}function rn(e,t){let n=e.collections&&e.collections[t];return n?n.resource||t:null}function as(e,t){let n=[],s=e.collections||{};for(let r of Object.keys(s)){let o=s[r];!H(o)||!o.tenant||(o.resource||r)===t&&n.indexOf(o.tenant)===-1&&n.push(o.tenant)}return n}var oe=(e,t)=>typeof t=="string"&&H(e)&&De(e.permissions,t);function cs(e,t,n,s){let r=n,o=!1;return H(n)&&((Object.keys(n).sort().join(",")!=="kind,upward"||n.upward!==!0)&&y(e+".scope."+t,"must be a scope kind, or { kind, upward: true }"),r=n.kind,o=!0),(typeof r!="string"||!r)&&y(e+".scope."+t,"must be a scope kind, or { kind, upward: true }"),s.indexOf(r)===-1&&y(e+".scope."+t,'"'+r+'" is not in catalogue.scopes ('+s.join(", ")+")"),o}function us(e,t,n,s,r){let o=".permissions."+n+".rules["+r+"]";H(s)||y(o,"must be an object"),s.subject!==void 0&&y(o+".subject","a catalogue rule names no subject: its holders come from grants");let a=is(s.actions);(s.actions===void 0||a.length===0)&&y(o+".actions","is required");for(let i of a)(typeof i!="string"||!i)&&y(o+".actions","must be a string or an array of strings"),i==="manage"&&y(o+".actions",'"manage" is not allowed in a catalogue rule: name the actions');(typeof s.resource!="string"||!s.resource)&&y(o+".resource","must be a string"),s.resource==="all"&&y(o+".resource",'"all" is not allowed: name a resource'),s.where!==void 0&&!H(s.where)&&y(o+".where","must be an object");let c=a.some(i=>i!==os);if(s.scope===void 0&&y(o+".scope",'is required: "any", or a map of row field to scope kind'),s.scope==="any"){c&&y(o+".scope",'"any" is only for read rules; a rule that writes must be placed by a scope map');return}(!H(s.scope)||Object.keys(s.scope).length===0)&&y(o+".scope",'must be "any" or a non-empty map of row field to scope kind');let f=0;for(let i of Object.keys(s.scope))cs(o,i,s.scope[i],t)||(f+=1);if(f===0&&y(o+".scope","has only upward fields; it needs at least one plain field, so it never reaches above its grant"),s.where)for(let i of Object.keys(s.where))De(s.scope,i)&&y(o+".where."+i,'repeats the scope field "'+i+'"');if(c)for(let i of as(e,s.resource))De(s.scope,i)||y(o+".scope","writes "+s.resource+', whose collection declares tenant field "'+i+'": pin it in the scope (plain or upward), so a write cannot move the row out of the grant')}function fs(e,t){let n=t.store;H(n)||y(".store","must be an object { roles, grants }");let s=e.collections||{};for(let i of["roles","grants"]){let d=n[i];(typeof d!="string"||!De(s,d))&&y(".store."+i,JSON.stringify(d)+" is not a key of policy.collections");for(let h of["owner","actor"])s[d][h]!==void 0&&y(".store."+i,'collection "'+d+'" declares '+h+': "'+s[d][h]+`". The gateway would stamp it with the writer's member id; a store collection declares no `+h)}n.roles===n.grants&&y(".store",'roles and grants name the same collection "'+n.roles+'"');let r=rn(e,n.roles),o=rn(e,n.grants);r===o&&y(".store",'the roles and grants collections share the resource "'+r+'"');let a=t.gates,c=i=>t.permissions[i].rules.map(d=>d.resource);if(a.roles!==a.grants){let i=[["roles",a.roles,r],["grants",a.grants,o]];for(let[d,h,l]of i)c(h).forEach((g,j)=>{g!==l&&y(".permissions."+h+".rules["+j+"].resource",'"'+g+'" is not the '+d+` collection's resource "`+l+'" (catalogue.gates.'+d+' is "'+h+'")')});return}let f=c(a.roles);f.forEach((i,d)=>{i!==r&&i!==o&&y(".permissions."+a.roles+".rules["+d+"].resource",'"'+i+'" is neither store resource ("'+r+'", "'+o+'")')});for(let i of[r,o])f.indexOf(i)===-1&&y(".gates",'the permission "'+a.roles+'" gates both writes but no rule of it names "'+i+'"')}function _e(e){let t=e.catalogue;H(t)||y("","must be an object");let n=t.scopes;(!Array.isArray(n)||n.length===0)&&y(".scopes","must be a non-empty array of scope kinds, outermost first");let s=[];n.forEach((r,o)=>{(typeof r!="string"||!r)&&y(".scopes["+o+"]","must be a non-empty string"),r===R&&y(".scopes["+o+"]",'"site" is reserved: it is implicit and contains everything'),s.indexOf(r)!==-1&&y(".scopes",'names "'+r+'" twice'),s.push(r)}),t.roleOwner!==void 0&&t.roleOwner!==n[0]&&y(".roleOwner",'must be scopes[0] ("'+n[0]+`"), the outermost kind, so an owner's path is { [roleOwner]: id }`),(!H(t.permissions)||Object.keys(t.permissions).length===0)&&y(".permissions","must be a non-empty object of permission name to { rules }");for(let r of Object.keys(t.permissions)){rs.test(r)||y(".permissions."+r,'is not a valid permission name (lower case words joined by ".", "_" or "-")');let o=t.permissions[r];H(o)||y(".permissions."+r,"must be an object { label?, rules }"),o.label!==void 0&&typeof o.label!="string"&&y(".permissions."+r+".label","must be a string"),(!Array.isArray(o.rules)||o.rules.length===0)&&y(".permissions."+r+".rules","must be a non-empty array"),o.rules.forEach((a,c)=>us(e,n,r,a,c))}H(t.gates)||y(".gates","is required: { roles, grants }, two declared permissions");for(let r of["roles","grants"]){let o=t.gates[r];oe(t,o)||y(".gates."+r,JSON.stringify(o)+" is not a declared permission")}if(t.subjects!==void 0){H(t.subjects)||y(".subjects",'must be an object of subject name to "*" or a permission list');for(let r of Object.keys(t.subjects)){let o=e.subjects&&e.subjects[r];o||y(".subjects."+r,"is not declared in policy.subjects"),typeof o.role!="string"&&y(".subjects."+r,"must be a role: subject; only a Wix member role can count as a site-wide grant");let a=t.subjects[r];if(a!=="*"){Array.isArray(a)||y(".subjects."+r,'must be "*" or an array of permission names');for(let c of a)oe(t,c)||y(".subjects."+r,JSON.stringify(c)+" is not a declared permission")}}}return t.store!==void 0&&fs(e,t),t}var ie={ANYONE:"anyone",ANONYMOUS:"anonymous",MEMBER:"member"},ne=e=>!!e&&typeof e=="object"&&!Array.isArray(e),ls=e=>Array.isArray(e)?e:[e];function N(e,t){throw new te("policy"+e+": "+t)}function ds(e,t){let n=".subjects."+e;ne(t)||N(n,"must be an object");let r=["when","role","domain"].filter(o=>t[o]!==void 0);if(r.length===0&&N(n,'needs exactly one of when/role/domain \u2014 "{}" is ambiguous between a visitor and a member'),r.length>1&&N(n,"has "+r.join(" and ")+"; use exactly one"),t.when!==void 0){let o=[ie.ANYONE,ie.ANONYMOUS,ie.MEMBER];o.indexOf(t.when)===-1&&N(n+".when","must be one of "+o.join(", ")+" (got "+JSON.stringify(t.when)+")")}t.role!==void 0&&typeof t.role!="string"&&N(n+".role","must be a string"),t.domain!==void 0&&typeof t.domain!="string"&&N(n+".domain","must be a string")}function ps(e,t,n){let s=".rules["+t+"]";ne(e)||N(s,"must be an object"),typeof e.subject!="string"&&N(s+".subject","must be a string"),n.indexOf(e.subject)===-1&&N(s+".subject",'"'+e.subject+'" is not declared in policy.subjects'),e.actions===void 0&&N(s+".actions","is required");for(let r of ls(e.actions))typeof r!="string"&&N(s+".actions","must be a string or an array of strings");typeof e.resource!="string"&&N(s+".resource","must be a string"),e.where!==void 0&&!ne(e.where)&&N(s+".where","must be an object")}var on=["Anyone","SiteMember","Admin"];function ms(e,t,n){let s=".api."+e;ne(t)||N(s,"must be an object"),on.indexOf(t.permission)===-1&&N(s+".permission","must be one of "+on.join(", ")+" (got "+JSON.stringify(t.permission)+")"),t.ability!==void 0&&((!Array.isArray(t.ability)||t.ability.length!==2)&&N(s+".ability","must be [action, resource]"),(typeof t.ability[0]!="string"||typeof t.ability[1]!="string")&&N(s+".ability","both entries must be strings")),t.subject!==void 0&&n.indexOf(t.subject)===-1&&N(s+".subject",'"'+t.subject+'" is not declared in policy.subjects')}var hs=["resource","owner","actor","tenant","profile"];function gs(e,t){let n=".collections."+e;ne(t)||N(n,"must be an object");for(let s of hs)t[s]!==void 0&&(typeof t[s]!="string"||!t[s])&&N(n+"."+s,"must be a non-empty string");t.owner!==void 0&&t.owner===t.actor&&N(n,'owner and actor must be different fields (both are "'+t.owner+'")')}function Me(e){if(!ne(e))throw new te("policy must be an object");ne(e.subjects)||N(".subjects","is required and must be an object");let t=Object.keys(e.subjects);t.length===0&&N(".subjects","declares no subjects");for(let n of t)ds(n,e.subjects[n]);if(Array.isArray(e.rules)||N(".rules","is required and must be an array"),e.rules.forEach((n,s)=>ps(n,s,t)),e.api!==void 0){ne(e.api)||N(".api","must be an object");for(let n of Object.keys(e.api))ms(n,e.api[n],t)}if(e.collections!==void 0){ne(e.collections)||N(".collections","must be an object");for(let n of Object.keys(e.collections))gs(n,e.collections[n])}return e.catalogue!==void 0&&_e(e),e}function he(e,t){let n=new Set(e.subjects||[]);for(let s of Object.keys(t.subjects)){let r=t.subjects[s];(r.when===ie.ANYONE||r.when===ie.ANONYMOUS&&!e.memberId||r.when===ie.MEMBER&&e.memberId||r.role!==void 0&&e.roles.indexOf(r.role)!==-1||r.domain!==void 0&&e.domain[r.domain])&&n.add(s)}return Array.from(n)}function an(e,t){let n=e.api&&e.api[t];return n?n.permission:null}var Ce=class{constructor(t,n){this.operator=t,this.value=n,Object.defineProperty(this,"t",{writable:!0})}get notes(){return this.t}addNote(t){this.t=this.t||[],this.t.push(t)}},Ie=class extends Ce{},le=class extends Ie{constructor(t,n){if(!Array.isArray(n))throw new Error(`"${t}" operator expects to receive an array of conditions`);super(t,n)}},ae="__itself__",de=class extends Ce{constructor(t,n,s){super(t,s),this.field=n}},at=new Ie("__null__",null),it=Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);function bs(e,t){return t instanceof le&&t.operator===e}function ct(e,t){return t.length===1?t[0]:new le(e,(function n(s,r,o){let a=o||[];for(let c=0,f=r.length;c<f;c++){let i=r[c];bs(s,i)?n(s,i.value,a):a.push(i)}return a})(e,t))}var ys=e=>e,cn=()=>Object.create(null),un=Object.defineProperty(cn(),"__@type@__",{value:"ignore value"});function Os(e,t,n=!1){if(!e||e&&e.constructor!==Object)return!1;for(let s in e)if(it(e,s)&&it(t,s)&&(!n||e[s]!==un))return!0;return!1}function ws(e){let t=[];for(let n in e)it(e,n)&&e[n]!==un&&t.push(n);return t}function rt(e,t){t!==at&&e.push(t)}var ut=e=>ct("and",e);var Te={compound(e,t,n){let s=(Array.isArray(t)?t:[t]).map(r=>n.parse(r));return new le(e.name,s)},field:(e,t,n)=>new de(e.name,n.field,t),document:(e,t)=>new Ie(e.name,t)},Ee=class{constructor(t,n=cn()){this.o=void 0,this.s=void 0,this.i=void 0,this.u=void 0,this.h=void 0,this.parse=this.parse.bind(this),this.u={operatorToConditionName:n.operatorToConditionName||ys,defaultOperatorName:n.defaultOperatorName||"eq",mergeFinalConditions:n.mergeFinalConditions||ut},this.o=Object.keys(t).reduce((s,r)=>(s[r]=Object.assign({name:this.u.operatorToConditionName(r)},t[r]),s),{}),this.s=Object.assign({},n.fieldContext,{field:"",query:{},parse:this.parse,hasOperators:s=>Os(s,this.o,n.useIgnoreValue)}),this.i=Object.assign({},n.documentContext,{parse:this.parse,query:{}}),this.h=n.useIgnoreValue?ws:Object.keys}setParse(t){this.parse=t,this.s.parse=t,this.i.parse=t}parseField(t,n,s,r){let o=this.o[n];if(!o)throw new Error(`Unsupported operator "${n}"`);if(o.type!=="field")throw new Error(`Unexpected ${o.type} operator "${n}" at field level`);return this.s.field=t,this.s.query=r,this.parseInstruction(o,s,this.s)}parseInstruction(t,n,s){return typeof t.validate=="function"&&t.validate(t,n),(t.parse||Te[t.type])(t,n,s)}parseFieldOperators(t,n){let s=[],r=this.h(n);for(let o=0,a=r.length;o<a;o++){let c=r[o];if(!this.o[c])throw new Error(`Field query for "${t}" may contain only operators or a plain object as a value`);rt(s,this.parseField(t,c,n[c],n))}return s}parse(t){let n=[],s=this.h(t);this.i.query=t;for(let r=0,o=s.length;r<o;r++){let a=s[r],c=t[a],f=this.o[a];if(f){if(f.type!=="document"&&f.type!=="compound")throw new Error(`Cannot use parsing instruction for operator "${a}" in "document" context as it is supposed to be used in "${f.type}" context`);rt(n,this.parseInstruction(f,c,this.i))}else this.s.hasOperators(c)?n.push(...this.parseFieldOperators(a,c)):rt(n,this.parseField(a,this.u.defaultOperatorName,c,t))}return this.u.mergeFinalConditions(n)}};function ot(e,t){let n=e[t];if(typeof n!="function")throw new Error(`Unable to interpret "${t}" condition. Did you forget to register interpreter for it?`);return n}function As(e){return e.operator}function fn(e,t){let n=t,s=n&&n.getInterpreterName||As,r;switch(n?n.numberOfArguments:0){case 1:r=a=>{let c=s(a,n);return ot(e,c)(a,o)};break;case 3:r=(a,c,f)=>{let i=s(a,n);return ot(e,i)(a,c,f,o)};break;default:r=(a,c)=>{let f=s(a,n);return ot(e,f)(a,c,o)}}let o=Object.assign({},n,{interpret:r});return o.interpret}function ln(e,t){return(n,...s)=>{let r=e(n,...s),o=t.bind(null,r);return o.ast=r,o}}var kr=Ee.prototype.parseInstruction;function dn(e,t){if(!Array.isArray(t))throw new Error(`"${e.name}" expects value to be an array`)}function pn(e,t){if(dn(e,t),!t.length)throw new Error(`"${e.name}" expects to have at least one element in array`)}var ft=e=>(t,n)=>{if(typeof n!==e)throw new Error(`"${t.name}" expects value to be a "${e}"`)},mn={type:"compound",validate:pn,parse(e,t,{parse:n}){let s=t.map(r=>n(r));return ct(e.name,s)}},js=mn,vs={type:"compound",validate:pn},xs={type:"field",validate(e,t){if(!(t&&(t instanceof RegExp||t.constructor===Object)))throw new Error(`"${e.name}" expects to receive either regular expression or object of field operators`)},parse(e,t,n){let s=t instanceof RegExp?new de("regex",n.field,t):n.parse(t,n);return new le(e.name,[s])}},lt={type:"field",validate(e,t){if(!t||t.constructor!==Object)throw new Error(`"${e.name}" expects to receive an object with nested query or field level operators`)},parse(e,t,{parse:n,field:s,hasOperators:r}){let o=r(t)?n(t,{field:ae}):n(t);return new de(e.name,s,o)}},dt={type:"field",validate:ft("number")},ke={type:"field",validate:dn},pt=ke,mt=ke,Is={type:"field",validate(e,t){if(!Array.isArray(t)||t.length!==2)throw new Error(`"${e.name}" expects an array with 2 numeric elements`)}},ht={type:"field",validate:ft("boolean")},Ue={type:"field",validate:function(e,t){if(!(typeof t=="string"||typeof t=="number"||t instanceof Date))throw new Error(`"${e.name}" expects value to be comparable (i.e., string, number or date)`)}},Ne=Ue,gt=Ne,bt=Ne,Ge={type:"field"},yt=Ge,Ot={type:"field",validate(e,t){if(!(t instanceof RegExp)&&typeof t!="string")throw new Error(`"${e.name}" expects value to be a regular expression or a string that represents regular expression`)},parse(e,t,n){let s=typeof t=="string"?new RegExp(t,n.query.$options||""):t;return new de(e.name,n.field,s)}},wt={type:"field",parse:()=>at},Es={type:"document",validate:ft("function")},ks=Object.freeze({__proto__:null,$and:mn,$or:js,$nor:vs,$not:xs,$elemMatch:lt,$size:dt,$in:ke,$nin:pt,$all:mt,$mod:Is,$exists:ht,$gte:Ue,$gt:Ne,$lt:gt,$lte:bt,$eq:Ge,$ne:yt,$regex:Ot,$options:wt,$where:Es}),Pe=class extends Ee{constructor(t){super(t,{defaultOperatorName:"$eq",operatorToConditionName:n=>n.slice(1)})}parse(t,n){return n&&n.field?ut(this.parseFieldOperators(n.field,t)):super.parse(t)}},Le=ks;function At(e,t,n){for(let s=0,r=e.length;s<r;s++)if(n(e[s],t)===0)return!0;return!1}function jt(e,t){return Array.isArray(e)&&Number.isNaN(Number(t))}function hn(e,t,n){if(!jt(e,t))return n(e,t);let s=[];for(let r=0;r<e.length;r++){let o=n(e[r],t);o!==void 0&&(s=s.concat(o))}return s}function pe(e){return(t,n,s)=>{let r=s.get(n,t.field);return Array.isArray(r)?r.some(o=>e(t,o,s)):e(t,r,s)}}var Ns=Object.hasOwn||Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty),$s=(e,t)=>e[t];function gn(e,t,n){let s=t.lastIndexOf(".");return s===-1?[e,t]:[n(e,t.slice(0,s)),t.slice(s+1)]}function Rs(e,t,n=$s){if(t===ae)return e;if(!e)throw new Error(`Unable to get field "${t}" out of ${String(e)}.`);return(function(s,r,o){if(r.indexOf(".")===-1)return hn(s,r,o);let a=r.split("."),c=s;for(let f=0,i=a.length;f<i;f++)if(c=hn(c,a[f],o),!c||typeof c!="object")return f<i-1?void 0:c;return c})(e,t,n)}function vt(e,t){return e===t?0:e>t?1:-1}function xt(e,t={}){return fn(e,Object.assign({get:Rs,compare:vt},t))}var bn=(e,t,{interpret:n})=>e.value.some(s=>n(s,t)),Fs=(e,t,n)=>!bn(e,t,n),It=(e,t,{interpret:n})=>e.value.every(s=>n(s,t)),Ss=(e,t,{interpret:n})=>!n(e.value[0],t),Be=(e,t,{compare:n,get:s})=>{let r=s(t,e.field);return Array.isArray(r)&&!Array.isArray(e.value)?At(r,e.value,n):n(r,e.value)===0},Et=(e,t,n)=>!Be(e,t,n),kt=pe((e,t,n)=>{let s=n.compare(t,e.value);return s===0||s===-1}),Nt=pe((e,t,n)=>n.compare(t,e.value)===-1),$t=pe((e,t,n)=>n.compare(t,e.value)===1),Rt=pe((e,t,n)=>{let s=n.compare(t,e.value);return s===0||s===1}),Ft=(e,t,{get:n})=>{if(e.field===ae)return t!==void 0;let[s,r]=gn(t,e.field,n),o=a=>a==null?!!a===e.value:Ns(a,r)===e.value;return jt(s,r)?s.some(o):o(s)},Ds=pe((e,t)=>typeof t=="number"&&t%e.value[0]===e.value[1]),St=(e,t,{get:n})=>{let[s,r]=gn(t,e.field,n),o=a=>{let c=n(a,r);return Array.isArray(c)&&c.length===e.value};return e.field!==ae&&jt(s,r)?s.some(o):o(s)},Dt=pe((e,t)=>typeof t=="string"&&e.value.test(t)),$e=pe((e,t,{compare:n})=>At(e.value,t,n)),_t=(e,t,n)=>!$e(e,t,n),Mt=(e,t,{compare:n,get:s})=>{let r=s(t,e.field);return Array.isArray(r)&&e.value.every(o=>At(r,o,n))},Ct=(e,t,{interpret:n,get:s})=>{let r=s(t,e.field);return Array.isArray(r)&&r.some(o=>n(e.value,o))},_s=(e,t)=>e.value.call(t),Ms=Object.freeze({__proto__:null,or:bn,nor:Fs,and:It,not:Ss,eq:Be,ne:Et,lte:kt,lt:Nt,gt:$t,gte:Rt,exists:Ft,mod:Ds,size:St,regex:Dt,within:$e,nin:_t,all:Mt,elemMatch:Ct,where:_s}),Ve=Object.assign({},Ms,{in:$e}),Dr=xt(Ve);function yn(e){return e===null||typeof e!="object"?e:e instanceof Date?e.getTime():e&&typeof e.toJSON=="function"?e.toJSON():e}var Cs=(e,t)=>vt(yn(e),yn(t));function qe(e,t,n){let s=new Pe(e),r=xt(t,Object.assign({compare:Cs},n));if(n&&n.forPrimitives){let o={field:ae},a=s.parse;s.setParse(c=>a(c,o))}return ln(s.parse,r)}var Pr=qe(Le,Ve),Ur=qe(["$and","$or"].reduce((e,t)=>(e[t]=Object.assign({},e[t],{type:"field"}),e),Object.assign({},Le,{$nor:Object.assign({},Le.$nor,{type:"field",parse:Te.compound})})),Ve,{forPrimitives:!0});var xn=Object.hasOwn||((e,t)=>Object.prototype.hasOwnProperty.call(e,t));function Tt(e){return Array.isArray(e)?e:[e]}var ge="__caslSubjectType__";function In(e,t){if(t){if(!xn(t,ge))Object.defineProperty(t,ge,{value:e});else if(e!==t[ge])throw new Error(`Trying to cast object to subject type ${e} but previously it was casted to ${t[ge]}`)}return t}var ze=e=>{let t=typeof e;return t==="string"||t==="function"},En=e=>e.modelName||e.name;function Ts(e){return typeof e=="string"?e:En(e)}function kn(e){return xn(e,ge)?e[ge]:En(e.constructor)}var On={function:e=>e.constructor,string:kn};function wn(e,t,n){for(let s=n;s<t.length;s++)e.push(t[s])}function An(e,t){if(!e||!e.length)return t||[];if(!t||!t.length)return e||[];let n=0,s=0,r=[];for(;n<e.length&&s<t.length;)e[n].priority<t[s].priority?(r.push(e[n]),n++):e[n].priority>t[s].priority?(r.push(t[s]),s++):(r.push(e[n]),n++,s++);return wn(r,e,n),wn(r,t,s),r}function Ke(e,t,n){let s=e.get(t);return s||(s=n(),e.set(t,s)),s}var Ps=e=>e;function Us(e,t){let n;for(let s=0;s<e.length;s++){let r=t(e[s]);n&&r&&n.push(e[s]),r||(n??=e.slice(0,s))}return n||e}function Gs(e,t){if(Array.isArray(e.fields)&&!e.fields.length)throw new Error("`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa");if(e.fields&&!t.fieldMatcher)throw new Error('You need to pass "fieldMatcher" option in order to restrict access by fields');if(e.conditions&&!t.conditionsMatcher)throw new Error('You need to pass "conditionsMatcher" option in order to restrict access by conditions')}var Pt=class{constructor(t,n,s=0){Gs(t,n),this.action=n.resolveAction(t.action),this.subject=t.subject,this.inverted=!!t.inverted,this.conditions=t.conditions,this.reason=t.reason,this.origin=t,this.fields=t.fields?Tt(t.fields):void 0,this.priority=s,this.t=n}i(){return this.conditions&&!this.o&&(this.o=this.t.conditionsMatcher(this.conditions)),this.o}get ast(){let t=this.i();return t?t.ast:void 0}matchesConditions(t){return this.conditions?!t||ze(t)?!this.inverted:this.i()(t):!0}matchesField(t){return this.fields?t?(this.u||(this.u=this.t.fieldMatcher(this.fields)),this.u(t)):!this.inverted:!0}};function Ls(e,t){let n={value:e,prev:t,next:null};return t&&(t.next=n),n}function Bs(e){e.next&&(e.next.prev=e.prev),e.prev&&(e.prev.next=e.next),e.next=e.prev=null}var jn=()=>({rules:[],merged:!1}),vn=()=>new Map,Ut=class{constructor(t=[],n={}){this.h=!1,this.l=new Map,this.p={conditionsMatcher:n.conditionsMatcher,fieldMatcher:n.fieldMatcher,resolveAction:n.resolveAction||Ps},this.$=n.anyAction||"manage",this.A=n.anySubjectType||"all",this.m=t,this.M=!!n.detectSubjectType,this.j=n.detectSubjectType||kn,this.v(t)}get rules(){return this.m}detectSubjectType(t){return ze(t)?t:t?this.j(t):this.A}update(t){let n={rules:t,ability:this,target:this};return this._("update",n),this.m=t,this.v(t),this._("updated",n),this}v(t){let n=new Map,s;for(let r=t.length-1;r>=0;r--){let o=t.length-r-1,a=new Pt(t[r],this.p,o),c=Tt(a.action),f=Tt(a.subject||this.A);!this.h&&a.fields&&(this.h=!0);for(let i=0;i<f.length;i++){let d=Ke(n,f[i],vn);s===void 0&&(s=typeof f[i]),typeof f[i]!==s&&s!=="mixed"&&(s="mixed");for(let h=0;h<c.length;h++)Ke(d,c[h],jn).rules.push(a)}}if(this.l=n,s!=="mixed"&&!this.M){let r=On[s]||On.string;this.j=r}}possibleRulesFor(t,n=this.A){if(!ze(n))throw new Error('"possibleRulesFor" accepts only subject types (i.e., string or class) as the 2nd parameter');let s=Ke(this.l,n,vn),r=Ke(s,t,jn);if(r.merged)return r.rules;let o=t!==this.$&&s.has(this.$)?s.get(this.$).rules:void 0,a=An(r.rules,o);return n!==this.A&&(a=An(a,this.possibleRulesFor(t,this.A))),r.rules=a,r.merged=!0,a}rulesFor(t,n,s){let r=this.possibleRulesFor(t,n);if(s&&typeof s!="string")throw new Error("The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details");return this.h?Us(r,o=>o.matchesField(s)):r}actionsFor(t){if(!ze(t))throw new Error('"actionsFor" accepts only subject types (i.e., string or class) as a parameter');let n=new Set,s=this.l.get(t);s&&Array.from(s.keys()).forEach(o=>n.add(o));let r=t!==this.A?this.l.get(this.A):void 0;return r&&Array.from(r.keys()).forEach(o=>n.add(o)),Array.from(n)}on(t,n){this.F=this.F||new Map;let s=this.F,r=s.get(t)||null,o=Ls(n,r);return s.set(t,o),()=>{let a=s.get(t);!o.next&&!o.prev&&a===o?s.delete(t):o===a&&s.set(t,o.prev),Bs(o)}}_(t,n){if(!this.F)return;let s=this.F.get(t)||null,r=[];for(;s!==null;)r.push(s.value),s=s.prev;for(let o=0;o<r.length;o++)r[o](n)}},Gt=class extends Ut{can(t,n,s){let r=this.relevantRuleFor(t,n,s);return!!r&&!r.inverted}relevantRuleFor(t,n,s){let r=this.detectSubjectType(n),o=this.rulesFor(t,r,s);for(let a=0,c=o.length;a<c;a++)if(o[a].matchesConditions(n))return o[a];return null}cannot(t,n,s){return!this.can(t,n,s)}},Vs={$eq:Ge,$ne:yt,$lt:gt,$lte:bt,$gt:Ne,$gte:Ue,$in:ke,$nin:pt,$all:mt,$size:dt,$regex:Ot,$options:wt,$elemMatch:lt,$exists:ht},qs={eq:Be,ne:Et,lt:Nt,lte:kt,gt:$t,gte:Rt,in:$e,nin:_t,all:Mt,size:St,regex:Dt,elemMatch:Ct,exists:Ft,and:It};var Ks=qe(Vs,qs),zs=/[-/\\^$+?.()|[\]{}]/g,Ws=/\.?\*+\.?/g,Js=/\*+/,Ys=/\./g;function Zs(e,t,n){let s=n[0]==="*"||e[0]==="."&&e[e.length-1]==="."?"+":"*",r=e.indexOf("**")===-1?"[^.]":".",o=e.replace(Ys,"\\$&").replace(Js,r+s);return t+e.length===n.length?`(?:${o})?`:o}function Hs(e,t,n){return e==="."&&(n[t-1]==="*"||n[t+1]==="*")?e:`\\${e}`}function Qs(e){let t=e.map(s=>s.replace(zs,Hs).replace(Ws,Zs)),n=t.length>1?`(?:${t.join("|")})`:t[0];return new RegExp(`^${n}$`)}var Xs=e=>{let t;return n=>(typeof t>"u"&&(t=e.every(s=>s.indexOf("*")===-1)?null:Qs(e)),t===null?e.indexOf(n)!==-1:t.test(n))};function Nn(e=[],t={}){return new Gt(e,Object.assign({conditionsMatcher:Ks,fieldMatcher:Xs},t))}var er=e=>`Cannot execute "${e.action}" on "${e.subjectType}"`,$n=function(t){this.message=t};$n.prototype=Object.create(Error.prototype);var Lt=class extends $n{static setDefaultMessage(t){this.P=typeof t=="string"?()=>t:t}static from(t){return new this(t)}constructor(t){super(""),this.ability=t,typeof Error.captureStackTrace=="function"&&(this.name="ForbiddenError",Error.captureStackTrace(this,this.constructor))}setMessage(t){return this.message=t,this}throwUnlessCan(t,n,s){let r=this.unlessCan(t,n,s);if(r)throw r}unlessCan(t,n,s){let r=this.ability.relevantRuleFor(t,n,s);if(r&&!r.inverted)return;this.action=t,this.subject=n,this.subjectType=Ts(this.ability.detectSubjectType(n)),this.field=s;let o=r?r.reason:"";return this.message=this.message||o||this.constructor.P(this),this}};Lt.P=er;var Kr=Object.freeze({__proto__:null});function Bt(e,t,n){if(e==null)return e;if(typeof e=="string"){if(e.indexOf("$principal.")!==0)return e;let r=e.slice(11).split(".").reduce((o,a)=>o==null?o:o[a],t);return r==null&&(n.unresolved=!0),r}if(Array.isArray(e))return e.map(s=>Bt(s,t,n));if(typeof e=="object"){let s={};for(let r of Object.keys(e))s[r]=Bt(e[r],t,n);return s}return e}function me(e,t){let n={unresolved:!1};return{conditions:Bt(e,t,n),unresolved:n.unresolved}}function Vt(e,t){return me(e,t).conditions}var K=e=>!!e&&typeof e=="object"&&!Array.isArray(e),ee=e=>typeof e=="string"&&e.length>0,We=e=>e.owner===null||e.owner===void 0;function be(e,t){e.indexOf(t)===-1&&e.push(t)}function tr(e,t){let n=t&&t.catalogue;if(!n||!K(n.subjects)||!e)return[];let s=Array.isArray(e.roles)?e.roles:[],r=[];for(let o of Object.keys(n.subjects)){let a=t.subjects&&t.subjects[o];if(!a||typeof a.role!="string"||s.indexOf(a.role)===-1)continue;let c=n.subjects[o],f=c==="*"?Object.keys(n.permissions):(Array.isArray(c)?c:[]).filter(i=>oe(n,i));r.push({subject:o,permissions:f})}return r}function nr(e,t,n,s){let r={},o=s.indexOf(t);for(let a=0;a<=o;a++){let c=s[a];ee(e[c])&&(r[c]=e[c])}return r[t]=n,r}function sr(e,t,n,s){let r={};for(let o of s){let a=[];for(let c of Array.isArray(e[o])?e[o]:[])ee(c)&&be(a,c);o===t&&be(a,n),a.length&&(r[o]=a)}return r}function Je(e,t,n){let s={grants:[],ignored:[]},r=e&&e.catalogue;if(!K(r)||!K(n))return s;let o=r.scopes,a=Array.isArray(n.roles)?n.roles:[],c=Array.isArray(n.grants)?n.grants:[],f=t&&ee(t.memberId)?t.memberId:null;for(let i of c){let d=(F,X)=>{let B={reason:F,grant:K(i)&&i._id!==void 0?i._id:null,role:K(i)&&i.role!==void 0?i.role:null};s.ignored.push(Object.assign(B,X||{}))};if(!K(i)){d("malformed");continue}if(!f||i.memberId!==f){d("notCaller");continue}if(i.isArchived===!0){d("archived");continue}if(i.status!==void 0&&i.status!==null&&i.status!==""&&i.status!=="ACTIVE"){d("inactive");continue}let h=i.scopeKind,l=h===R;if(!(l?i.scopeId===null||i.scopeId===void 0:o.indexOf(h)!==-1&&ee(i.scopeId))){d("unknownScope");continue}let j=K(i.path)?i.path:{};if(!l&&j[h]!==void 0&&j[h]!==i.scopeId){d("badPath");continue}let x=null;if(ee(i.role)){for(let F of a)if(K(F)&&F._id===i.role){x=F;break}}if(!x){d("roleNotFound");continue}if(x.isArchived===!0){d("roleArchived");continue}let P=l?{}:nr(j,h,i.scopeId,o),q=We(x)?null:x.owner;if(q!==null&&!(ee(q)&&ee(r.roleOwner)&&!l&&ee(P[r.roleOwner])&&P[r.roleOwner]===q)){d("outsideOwner");continue}let L=[],U=[];for(let F of Array.isArray(x.permissions)?x.permissions:[])oe(r,F)?be(L,F):U.indexOf(F)===-1&&(U.push(F),d("unknownPermission",{permission:F}));s.grants.push({id:i._id!==void 0?i._id:null,role:x._id,roleOwner:q,scope:{kind:h,id:l?null:i.scopeId},path:P,covers:l?{}:sr(K(i.covers)?i.covers:{},h,i.scopeId,o),permissions:L})}return s}function qt(e,t){let n=[];for(let s of e&&Array.isArray(e.grants)?e.grants:[])!K(s)||!K(s.scope)||!Array.isArray(s.permissions)||n.push({scope:{kind:s.scope.kind,id:s.scope.kind===R?null:s.scope.id},permissions:s.permissions,covers:K(s.covers)?s.covers:{},path:K(s.path)?s.path:{}});for(let s of tr(e,t))n.push({scope:{kind:R,id:null},permissions:s.permissions,covers:{},path:{},subject:s.subject});return n}function Rn(e,t){let n=K(t),s=n?t.kind:t,r=[];for(let o of Array.isArray(e.covers[s])?e.covers[s]:[])ee(o)&&be(r,o);return n&&ee(e.path[s])&&be(r,e.path[s]),r}function rr(e,t){let n=t.catalogue,s=qt(e,t);if(s.length===0)return[];let r=[],o={},a=c=>{let f=JSON.stringify(c);o[f]||(o[f]=!0,r.push(c))};for(let c of Object.keys(n.permissions)){let f=s.filter(i=>i.permissions.indexOf(c)!==-1);if(f.length!==0)for(let i of n.permissions[c].rules){let d=null;if(i.where){let g=me(i.where,e);if(g.unresolved)continue;d=g.conditions}let h=Array.isArray(i.actions)?i.actions.slice():i.actions;if(i.scope==="any"||f.some(g=>g.scope.kind===R)){let g={action:h,subject:i.resource};d&&(g.conditions=d),a(g);continue}let l=Object.keys(i.scope);if(l.length===1){let g=l[0],j=[];for(let x of f)for(let P of Rn(x,i.scope[g]))be(j,P);if(j.length===0)continue;a({action:h,subject:i.resource,conditions:Object.assign({},d||{},{[g]:{$in:j}})});continue}for(let g of f){let j=Object.assign({},d||{}),x=!0;for(let P of l){let q=Rn(g,i.scope[P]);if(q.length===0){x=!1;break}j[P]={$in:q}}x&&a({action:h,subject:i.resource,conditions:j})}}}return r}var Fn="__wixAccessGrantRules";function Ye(e,t){if(!t||!K(t.catalogue)||!e||typeof e!="object")return[];let n=e[Fn];if(n&&n.policy===t&&n.grants===e.grants&&n.roles===e.roles&&n.domain===e.domain&&n.subjects===e.subjects&&n.memberId===e.memberId)return n.rules.slice();let s=rr(e,t);try{Object.defineProperty(e,Fn,{value:{policy:t,grants:e.grants,roles:e.roles,domain:e.domain,subjects:e.subjects,memberId:e.memberId,rules:s},enumerable:!1,configurable:!0,writable:!0})}catch{}return s.slice()}function ce(e,t){let n=he(e,t),s=[];for(let r of t.rules){if(n.indexOf(r.subject)===-1)continue;let o={action:r.actions,subject:r.resource};if(r.where){let{conditions:a,unresolved:c}=me(r.where,e);if(c)continue;o.conditions=a}s.push(o)}if(t.catalogue)for(let r of Ye(e,t))s.push(r);return s}function Kt(e){return Nn(Array.isArray(e)?e:[])}function Ze(e,t){return Kt(ce(e,t))}function T(e,t,n,s){return s==null?e.can(t,n):e.can(t,In(n,Object.assign({},s)))}var W={ALL:"all",NONE:"none",FIELDS:"fields",AMBIGUOUS:"ambiguous"},Sn={$in:"in",$nin:"nin",$ne:"ne",$gt:"gt",$gte:"gte",$lt:"lt",$lte:"lte"};function or(e){let t=[];for(let n of Object.keys(e)){let s=e[n];if(s===null||typeof s!="object"||Array.isArray(s)){t.push({field:n,op:"eq",value:s});continue}let r=Object.keys(s);if(r.length!==1||!Sn[r[0]])return null;t.push({field:n,op:Sn[r[0]],value:s[r[0]]})}return t}var ir=(e,t)=>e==="manage"||e===t||Array.isArray(e)&&(e.indexOf(t)!==-1||e.indexOf("manage")!==-1),ar=(e,t)=>e==="all"||e===t,Dn=e=>typeof e=="string"||typeof e=="number"&&Number.isFinite(e);function cr(e){let t=null,n=[];for(let s of e){let r=Object.keys(s.conditions);if(r.length!==1)return null;if(t===null)t=r[0];else if(r[0]!==t)return null;let o=s.conditions[t];if(Dn(o)){n.indexOf(o)===-1&&n.push(o);continue}if(!o||typeof o!="object"||Array.isArray(o))return null;let a=Object.keys(o);if(a.length!==1||a[0]!=="$in"||!Array.isArray(o.$in)||!o.$in.every(Dn))return null;for(let c of o.$in)n.indexOf(c)===-1&&n.push(c)}return{field:t,values:n}}function He(e,t,n,s){let r=ce(e,t).filter(a=>ir(a.action,n)&&ar(a.subject,s));if(r.length===0)return{scope:W.NONE,clauses:[]};if(r.some(a=>!a.conditions))return{scope:W.ALL,clauses:[]};if(r.length>1){let a=cr(r);return a?a.values.length===0?{scope:W.NONE,clauses:[]}:{scope:W.FIELDS,clauses:[{field:a.field,op:"in",value:a.values}]}:{scope:W.AMBIGUOUS,clauses:[]}}let o=or(r[0].conditions);return o?{scope:W.FIELDS,clauses:o}:{scope:W.AMBIGUOUS,clauses:[]}}function Qe(e,t){let n=e;for(let s of t)s.op==="in"?n=n.hasSome(s.field,s.value):s.op==="nin"?n=n.not(n.hasSome(s.field,s.value)):n=n[s.op](s.field,s.value);return n}var zt=/export\s+const\s+([A-Za-z0-9_$]+)\s*=\s*webMethod\s*\(\s*Permissions\s*\.\s*([A-Za-z0-9_$]+)/g,ur=[[/export\s*{\s*[A-Za-z0-9_$,\s]+}/,"export { x } \u2014 the call and the export must be one statement"],[/export\s+const\s+[A-Za-z0-9_$]+\s*=\s*webMethod\s*\(\s*Permissions\s*\[/,"Permissions['X'] \u2014 the property must be dotted and literal"],[/export\s+const\s+[A-Za-z0-9_$]+\s*=\s*webMethod\s*\(\s*[A-Za-z0-9_$]+\s*\(/,"a computed permission \u2014 it must be written out as Permissions.LEVEL"]];function Wt(e){let t={},n=String(e||"");zt.lastIndex=0;let s=zt.exec(n);for(;s;)t[s[1]]=s[2],s=zt.exec(n);return t}function Jt(e,t,n){let s=n||{},r=t&&t.api||{},o=Wt(e),a=String(e||""),c=[],f=[];for(let l of Object.keys(o)){let g=r[l];g?g.permission!==o[l]&&c.push({name:l,declared:g.permission,written:o[l]}):f.push({name:l,gate:o[l]})}let i=s.complete?Object.keys(r).filter(l=>!(l in o)):[],d=[];for(let[l,g]of ur)l.test(a)&&d.push(g);return{ok:c.length+f.length+i.length+d.length===0,found:o,mismatched:c,undeclared:f,missing:i,suspect:d}}function _n(e,t,n){let s=Jt(e,t,n);if(s.ok)return!0;let r=[];for(let o of s.mismatched)r.push(o.name+": policy says "+o.declared+", the export says "+o.written);for(let o of s.undeclared)r.push(o.name+": gated "+o.gate+" but missing from policy.api");for(let o of s.missing)r.push(o+": declared in policy.api but not exported here");for(let o of s.suspect)r.push("unreachable export shape \u2014 "+o);throw new Error(`wix-access: web-method gates do not match the policy:
|
|
2
|
+
`+r.join(`
|
|
3
|
+
`))}function Mn(e,t){let n=t&&t.api||{},s=e||{},r={},o=[];for(let a of Object.keys(s)){let c=s[a],f=n[a];if(!f){o.push(a);continue}if(typeof c!="function"){o.push(a+" (not a function: "+typeof c+")");continue}try{c.permission=f.permission,r[a]=f.permission}catch(i){o.push(a+" (could not stamp: "+String(i&&i.message)+")")}}if(o.length)throw new Error("wix-access: applyGates could not gate: "+o.join(", ")+". Every exported web method must be declared in policy.api.");return r}var M=e=>!!e&&typeof e=="object"&&!Array.isArray(e),z=e=>typeof e=="string"&&e.length>0,ye="defineRole",ue="grantRole",Yt={kind:R,id:null,path:{}};function Xe(e,t){return!t||!M(t.catalogue)||!e?[]:qt(e,t).map(n=>{let s={scope:{kind:n.scope.kind,id:n.scope.id},permissions:n.permissions.slice()};return n.subject&&(s.source="subject",s.subject=n.subject),s})}function Zt(e,t){return M(e)?e.kind===R?!0:!z(e.kind)||!z(e.id)||!M(t)||!M(t.path)?!1:t.path[e.kind]===e.id:!1}function Oe(e,t,n){return Array.isArray(e)?e.some(s=>M(s)&&Array.isArray(s.permissions)&&s.permissions.indexOf(t)!==-1&&Zt(s.scope,n)):!1}var et=e=>e&&M(e.catalogue)?e.catalogue:null;function Tn(e,t){let n=[];for(let s of Array.isArray(e.permissions)?e.permissions:[])oe(t,s)&&n.indexOf(s)===-1&&n.push(s);return n}function fr(e,t){if(We(e))return Yt;let n=z(t.roleOwner)?t.roleOwner:"owner";return z(e.owner)&&z(t.roleOwner)?{kind:n,id:e.owner,path:{[n]:e.owner}}:{kind:n,id:e.owner,path:{}}}function Pn(){let e=[],t=[];return{list:e,add(n,s,r){let o=s+"|"+(r&&r.value!==void 0?JSON.stringify(r.value):n);t.indexOf(o)===-1&&(t.push(o),e.push(Object.assign({path:n,code:s},r||{})))}}}function Ht(e,t){if(!M(e))return[{path:"",code:"notAnObject"}];let n=et(t)||{},s=Pn();return z(e.name)||s.add("name","missing"),Array.isArray(e.permissions)?e.permissions.forEach((r,o)=>{oe(n,r)||s.add("permissions["+o+"]","unknownPermission",{value:r})}):s.add("permissions","notAnArray"),e.owner===void 0?s.add("owner","ownerMissing"):e.owner!==null&&(z(n.roleOwner)?z(e.owner)||s.add("owner","notAString"):s.add("owner","noRoleOwner")),e.isArchived!==void 0&&typeof e.isArchived!="boolean"&&s.add("isArchived","notABoolean"),s.list}function Re(e,t,n){if(!M(e))return[{path:"",code:"notAnObject"}];let s=et(t)||{},r=Array.isArray(s.scopes)?s.scopes:[],o=Pn(),a=z(e.memberId),c=z(e.email);if(e.memberId!==void 0&&e.memberId!==null&&!a&&o.add("memberId","notAString"),e.email!==void 0&&e.email!==null&&!c&&o.add("email","notAString"),!a&&!c&&o.add("memberId","missing"),!z(e.role))o.add("role","missing");else if(Array.isArray(n)){let f=n.filter(i=>M(i)&&i._id===e.role)[0];f?f.isArchived===!0&&o.add("role","roleArchived"):o.add("role","roleNotFound")}return e.scopeKind===R?e.scopeId!==null&&e.scopeId!==void 0&&o.add("scopeId","notNull"):r.indexOf(e.scopeKind)!==-1?z(e.scopeId)||o.add("scopeId","missing"):o.add("scopeKind","unknownScope"),e.isArchived!==void 0&&typeof e.isArchived!="boolean"&&o.add("isArchived","notABoolean"),e.status!==void 0&&e.status!==null&&typeof e.status!="string"&&o.add("status","notAString"),o.list}function we(e,t,n){let s=et(t);if(!s)return A(m.INVALID_ARGUMENT,ye,{reason:"noCatalogue"});let r=n&&M(n.before)?n.before:null,o=n&&M(n.after)?n.after:null;if(!r&&!o)return A(m.INVALID_ARGUMENT,ye,{reason:"nothingToCheck"});if(o){let c=Ht(o,t),f=c.filter(i=>i.code==="unknownPermission").map(i=>i.value);if(f.length)return A(m.INVALID_ARGUMENT,ye,{reason:"unknownPermission",permissions:f});if(c.length)return A(m.INVALID_ARGUMENT,ye,{reason:"invalidRow",problems:c})}let a=[["before",r],["after",o]];for(let[c,f]of a){if(!f)continue;let i=fr(f,s);if(!Oe(e,s.gates.roles,i))return A(m.FORBIDDEN,ye,{reason:"noGate",side:c});let d=Tn(f,s).filter(h=>!Oe(e,h,i));if(d.length)return A(m.FORBIDDEN,ye,{reason:"escalation",side:c,missing:d})}return ve(null)}function Cn(e,t){return!M(e)||!M(t)?!1:t.scopeKind===R?e.kind===R:e.kind===t.scopeKind&&e.id===t.scopeId&&M(e.path)&&z(t.scopeId)&&e.path[t.scopeKind]===t.scopeId}function Ae(e,t,n){let s=et(t);if(!s)return A(m.INVALID_ARGUMENT,ue,{reason:"noCatalogue"});let r=M(n)?n:{},o=M(r.before)?r.before:null,a=M(r.after)?r.after:null;if(!o&&!a)return A(m.INVALID_ARGUMENT,ue,{reason:"nothingToCheck"});let c=[];if(o){let f=null;o.scopeKind===R?f=Yt:Cn(r.beforeScope,o)&&(f=r.beforeScope),c.push({side:"before",role:M(r.beforeRole)?r.beforeRole:null,place:f})}if(a){let f=Re(a,t);if(f.length)return A(m.INVALID_ARGUMENT,ue,{reason:"invalidRow",problems:f});let i=r.role;if(!M(i)||i._id!==a.role||i.isArchived===!0)return A(m.INVALID_ARGUMENT,ue,{reason:"roleNotFound"});let d=a.scopeKind===R&&(r.scope===void 0||r.scope===null)?Yt:r.scope;if(!Cn(d,a))return A(m.INVALID_ARGUMENT,ue,{reason:"unknownScope"});c.push({side:"after",role:i,place:d})}for(let{side:f,role:i,place:d}of c){if(!Oe(e,s.gates.grants,d))return A(m.FORBIDDEN,ue,{reason:"noGate",side:f});if(!i)continue;if(f==="after"&&!We(i)&&!(z(i.owner)&&z(s.roleOwner)&&M(d.path)&&d.path[s.roleOwner]===i.owner))return A(m.FORBIDDEN,ue,{reason:"outsideOwner",side:f});let h=Tn(i,s).filter(l=>!Oe(e,l,d));if(h.length)return A(m.FORBIDDEN,ue,{reason:"escalation",side:f,missing:h})}return ve(null)}var Qt="0.6.0";var Xt=[{action:"read",type:"Booking",object:{customerId:"m-1"}},{action:"read",type:"Booking",object:{customerId:"m-2"}},{action:"cancel",type:"Booking",object:{customerId:"m-1"}},{action:"delete",type:"Booking",object:{customerId:"m-1"}},{action:"manage",type:"Vendor",object:{_id:"v-1"}}];function Un(e){return Xt.map(t=>({action:t.action,type:t.type,object:t.object,can:T(e,t.action,t.type,t.object)}))}function Gn(e,t){let{wixUsers:n,currentMember:s}=e,r=t&&t.enrich||null,o=t&&t.onError||null;return async function(){let c=null,f=!1,i=!1;try{c=n.currentUser&&n.currentUser.id||null,f=!!(n.currentUser&&n.currentUser.loggedIn)}catch(l){i=!0,o&&o("resolveCaller.id",l)}let d=[];if(c)try{d=await s.getRoles()}catch(l){i=!0,o&&o("resolveCaller.roles",l)}let h=xe({kind:c?re.MEMBER:re.VISITOR,memberId:c,roles:d,unverified:i});if(h.loggedIn=f,r)try{let l=await r(h);l&&typeof l=="object"&&(h.domain=l)}catch(l){h.unverified=!0,o&&o("resolveCaller.enrich",l)}return h}}var lr="Admin";function Ln(e,t,n){let s=n.resolveCaller,r=n.abilityFor,o=n.audit||null;function a(f,i,d,h){return o&&o({event:"access.denied",action:f,code:i,caller:d?d.memberId:null,detail:h||null}),A(i,f)}function c(f,i,d){return i==="Anyone"?null:d.memberId?i==="Admin"&&!Se(d,lr)?a(f,m.FORBIDDEN,d,{gate:i}):null:a(f,m.UNAUTHENTICATED,d)}return function(i,d,h){let l=e.api&&e.api[i]||null;if(!l)throw new Error('wix-access: web method "'+i+'" is not declared in policy.api. Add it, or the gate it runs behind is undocumented.');let g=h||{},j=l.permission,x=l.ability||null,P=g.strip||[];return async function(...q){let L=await s();if(L.unverified)return a(i,m.UNVERIFIED,L);let U=c(i,j,L);if(U)return U;let F=q.map(B=>{if(!B||typeof B!="object"||Array.isArray(B))return B;let Z=Object.assign({},B);for(let je of P)delete Z[je];return Z}),X=null;if(x){let[B,Z]=x;if(g.load){if(X=await g.load(...F),!X)return a(i,m.NOT_FOUND,L);if(!T(r(L),B,Z,X))return Y(i)}else if(!T(r(L),B,Z))return a(i,m.FORBIDDEN,L)}return d({principal:L,subject:X},...F)}}}function Bn(e,t){let n=Object.keys(e&&e.api||{}),s=t.filter(r=>n.indexOf(r)===-1);if(s.length)throw new Error("wix-access: web methods missing from policy.api: "+s.join(", "));return!0}var Vn=100,dr=100,G="assignOwner";function qn(e,t,n){let{items:s,auth:r}=t,o=n.abilityFor,a=n.audit||null,c=n.onError||null;function f(u){if(a)try{a(u)}catch(p){c&&c("audit",p)}}let i={query:(...u)=>r.elevate(s.query)(...u),get:(...u)=>r.elevate(s.get)(...u),insert:(...u)=>r.elevate(s.insert)(...u),update:(...u)=>r.elevate(s.update)(...u),remove:(...u)=>r.elevate(s.remove)(...u)},d=n.namespace||null,h=u=>{let p=e.collections||{};return p[u]?p[u]:d&&typeof u=="string"&&u.indexOf(d)===0&&p[u.slice(d.length)]||null},l=u=>{let p=h(u);return p&&p.owner?p.owner:null},g=u=>{let p=h(u);return p&&p.actor?p.actor:null},j=u=>{let p=h(u);return p&&p.resource||u},x=e.catalogue||null,P=x&&x.store?x.store:null,q=n.heldFor,L=n.scopeOf||null,U=u=>{let p=e.collections||{};return p[u]?u:d&&typeof u=="string"&&u.indexOf(d)===0&&p[u.slice(d.length)]?u.slice(d.length):null},F=u=>{if(!P)return null;let p=U(u);return p!==null&&p===P.roles?"roles":p!==null&&p===P.grants?"grants":null},X=u=>{let p=U(u);return u.slice(0,u.length-p.length)+P.roles},B=u=>typeof u=="string"&&u.length>0;function Z(u,p,v,O){if(u.code===m.FORBIDDEN){let w=u.detail||{};f({event:"access.escalation",action:u.action,caller:p.memberId||null,collection:v,id:O===void 0?null:O,reason:w.reason||null,missing:w.missing||[]})}return u}let je=(u,p,v)=>we(q(u),e,{before:p,after:v});async function tt(u,p,v,O){if(O){let b=Re(O,e);if(b.length)return A(m.INVALID_ARGUMENT,"grantRole",{reason:"invalidRow",problems:b})}let w=[],k=[],I=[],_=b=>b&&b.scopeKind!==R&&x.scopes.indexOf(b.scopeKind)!==-1&&B(b.scopeId);for(let b of[v,O])b&&B(b.role)&&w.indexOf(b.role)===-1&&w.push(b.role);for(let b of[v,O]){if(!_(b))continue;let $=b.scopeKind+"/"+b.scopeId;k.indexOf($)===-1&&(k.push($),I.push({kind:b.scopeKind,id:b.scopeId}))}let E,C;try{let b=X(p),$=w.map(J=>i.get(b,J)).concat(I.map(J=>L({kind:J.kind,id:J.id}))),V=await Promise.all($);E=V.slice(0,w.length),C=V.slice(w.length)}catch(b){return c&&c("db.grantWrite",b),A(m.UNVERIFIED,"grantRole")}let D=b=>{if(!b)return null;let $=w.indexOf(b.role);return $===-1?null:E[$]||null},S=b=>{if(!b)return null;if(b.scopeKind===R)return{kind:R,id:null,path:{}};let $=k.indexOf(b.scopeKind+"/"+b.scopeId),V=$===-1?null:C[$];return!V||typeof V!="object"||!V.path||typeof V.path!="object"||V.path[b.scopeKind]!==b.scopeId?null:{kind:b.scopeKind,id:b.scopeId,path:Object.assign({},V.path)}},Q=S(O);return O&&!Q?A(m.INVALID_ARGUMENT,"grantRole",{reason:"unknownScope"}):Ae(q(u),e,{before:v,after:O,role:D(O),beforeRole:D(v),scope:Q,beforeScope:S(v)})}async function Yn(u,p){let v=[],O=await u.limit(Math.min(p||Vn,Vn)).find(),w=0;for(;O;){for(let k of O.items)v.push(k);if(p&&v.length>=p)return v.slice(0,p);if(!O.hasNext||!O.hasNext()||++w>=dr)break;O=await O.next()}return v}return{async query(u,p){let{principal:v,action:O="read",limit:w}=p,k=j(u),I=He(v,e,O,k);if(I.scope===W.NONE)return{ok:!0,data:[],scope:I.scope};let _=i.query(u);I.scope===W.FIELDS&&(_=Qe(_,I.clauses));let E=await Yn(_,I.scope===W.AMBIGUOUS?null:w);if(I.scope!==W.AMBIGUOUS)return{ok:!0,data:E,scope:I.scope};let C=o(v),D=E.filter(S=>T(C,O,k,S));return{ok:!0,data:w?D.slice(0,w):D,scope:I.scope}},async get(u,p,v){let{principal:O,action:w="read"}=v,k=j(u),I=await i.get(u,p);return I?T(o(O),w,k,I)?{ok:!0,data:I}:Y(w):Y(w)},async insert(u,p,v){let{principal:O,action:w="create",onBehalfOf:k,system:I=!1}=v,_=j(u),E=l(u),C=g(u),D=O.memberId||null;if(k!==void 0){if(!E)return A(m.INVALID_ARGUMENT,w,{reason:u+" declares no owner field"});if(typeof k!="string"||!k)return A(m.INVALID_ARGUMENT,w,{reason:"onBehalfOf must be a member id"})}else if(I)return A(m.INVALID_ARGUMENT,w,{reason:"system is only meaningful with onBehalfOf"});let S=Object.assign({},p),Q=F(u);Q==="roles"&&S.owner===void 0&&(S.owner=null);let b=k!==void 0?k:D,$=b!==D;E&&(S[E]=b),C&&(S[C]=D);let V=o(O);if($&&!I&&!T(V,G,_,S))return f({event:"access.denied",action:G,code:m.FORBIDDEN,caller:D,detail:{collection:u,owner:b}}),A(m.FORBIDDEN,G);if(!T(V,w,_,S))return A(m.FORBIDDEN,w);if(Q==="roles"){let fe=je(O,null,S);if(!fe.ok)return Z(fe,O,u,S._id)}else if(Q==="grants"){let fe=await tt(O,u,null,S);if(!fe.ok)return Z(fe,O,u,S._id)}let J=await i.insert(u,S);return $&&f({event:"access.onBehalf",action:w,caller:D,owner:b,system:I,collection:u,id:J&&J._id}),{ok:!0,data:J}},async update(u,p,v,O){let{principal:w,action:k="update",merge:I}=O;if(O.onBehalfOf!==void 0)return A(m.INVALID_ARGUMENT,k,{reason:"onBehalfOf is for insert; an update carries the new owner in its changes"});if(I!==void 0&&typeof I!="function")return A(m.INVALID_ARGUMENT,k,{reason:"merge must be a function (existing, changes) => row"});let _=j(u),E=await i.get(u,p);if(!E)return Y(k);let C=o(w);if(!T(C,k,_,E))return Y(k);let D=l(u),S=g(u),Q=w.memberId||null,b=I?I(E,v):Object.assign({},E,v),$=Object.assign({},b,{_id:p});S&&($[S]=E[S]);let V=F(u);V==="roles"&&$.owner===void 0&&($.owner=null);let J=null;if(D){let se=E[D]===void 0?null:E[D],nt=$[D]===void 0?null:$[D];nt!==se&&(T(C,G,_,E)&&T(C,G,_,$)?J={from:se,to:nt}:($[D]=E[D],f({event:"access.denied",action:G,code:m.FORBIDDEN,caller:Q,detail:{collection:u,id:p,owner:nt}})))}if(!T(C,k,_,$))return A(m.FORBIDDEN,k);if(V==="roles"){let se=je(w,E,$);if(!se.ok)return Z(se,w,u,p)}else if(V==="grants"){let se=await tt(w,u,E,$);if(!se.ok)return Z(se,w,u,p)}let fe=await i.update(u,$);return J&&f({event:"access.transfer",action:G,caller:Q,from:J.from,owner:J.to,system:!1,collection:u,id:p}),{ok:!0,data:fe}},async transfer(u,p,v,O){let{principal:w,system:k=!1}=O,I=j(u),_=l(u),E=w.memberId||null;if(F(u))return A(m.INVALID_ARGUMENT,G,{reason:"roles and grants have no owner to transfer"});if(!_)return A(m.INVALID_ARGUMENT,G,{reason:u+" declares no owner field"});if(v!==null&&(typeof v!="string"||!v))return A(m.INVALID_ARGUMENT,G,{reason:"newOwner must be a member id or null"});let C=await i.get(u,p);if(!C)return Y(G);let D=Object.assign({},C,{_id:p,[_]:v});if(!k){let b=o(w);if(!T(b,G,I,C)||!T(b,G,I,D))return f({event:"access.denied",action:G,code:m.FORBIDDEN,caller:E,detail:{collection:u,id:p}}),Y(G)}let S=C[_]===void 0?null:C[_];if(S===v)return{ok:!0,data:C};let Q=await i.update(u,D);return f({event:"access.transfer",action:G,caller:E,from:S,owner:v,system:k,collection:u,id:p}),{ok:!0,data:Q}},async remove(u,p,v){let{principal:O,action:w="delete"}=v,k=j(u),I=await i.get(u,p);if(!I)return Y(w);if(!T(o(O),w,k,I))return Y(w);let _=F(u);if(_==="roles"){let E=je(O,I,null);if(!E.ok)return Z(E,O,u,p)}else if(_==="grants"){let E=await tt(O,u,I,null);if(!E.ok)return Z(E,O,u,p)}return{ok:!0,data:await i.remove(u,p)}}}}function Kn(e,t,n){Me(e);let s=n||{};if(s.namespace!==void 0&&(typeof s.namespace!="string"||!s.namespace))throw new Error('wix-access: options.namespace must be a non-empty string, e.g. "@scope/app/"');if(s.grants!==void 0&&typeof s.grants!="function")throw new Error("wix-access: options.grants must be a function (principal) => ({ roles, grants })");if(s.scopeOf!==void 0&&typeof s.scopeOf!="function")throw new Error("wix-access: options.scopeOf must be a function ({ kind, id }) => ({ kind, id, path })");if(s.grants&&!e.catalogue)throw new Error("wix-access: a grants hook needs a catalogue (policy.catalogue) to compile them against");if(e.catalogue&&e.catalogue.store&&!s.scopeOf)throw new Error("wix-access: catalogue.store needs options.scopeOf, so the gateway can place each grant it is asked to write");let r=l=>{if(s.audit)try{s.audit(l)}catch(g){s.onError&&s.onError("audit",g)}},o=Gn(t,{enrich:s.enrich,onError:s.onError}),a=async()=>{let l=await o();if(l.subjects=he(l,e),Array.isArray(l.grants)||(l.grants=[]),e.catalogue&&s.grants&&l.memberId&&!l.unverified){let g;try{g=await s.grants(l)}catch(x){return l.unverified=!0,s.onError&&s.onError("resolveCaller.grants",x),l}let j=Je(e,l,g);l.grants=j.grants;for(let x of j.ignored)r({event:"access.ignored",reason:x.reason,caller:l.memberId,grant:x.grant,role:x.role,permission:x.permission===void 0?null:x.permission})}return l},c=l=>Ze(l,e),f=l=>Xe(l,e),i=async()=>{let l=await a();if(l.unverified)return A(m.UNVERIFIED,"accessForCaller");let g=ce(l,e),j=e.catalogue;if(!j)return JSON.parse(JSON.stringify({rules:g,grants:null}));let x=f(l),P=[],q=[],L=(U,F,X)=>{let B=U+"/"+F;q.indexOf(B)===-1&&(q.push(B),P.push({kind:U,id:F,path:X}))};for(let U of l.grants)U.scope.kind===R?L(R,null,{}):L(U.scope.kind,U.scope.id,U.path);return x.some(U=>U.scope.kind===R)&&L(R,null,{}),JSON.parse(JSON.stringify({rules:g,grants:{held:x,gates:{roles:j.gates.roles,grants:j.gates.grants},roleOwner:j.roleOwner||null,scopes:j.scopes.slice(),permissions:Object.keys(j.permissions),places:P}}))},d=Ln(e,t,{resolveCaller:a,abilityFor:c,audit:s.audit}),h=qn(e,t,{abilityFor:c,heldFor:f,scopeOf:s.scopeOf,audit:s.audit,onError:s.onError,namespace:s.namespace});return{policy:e,resolveCaller:a,abilityFor:c,guard:d,db:h,gateFor:l=>{let g=e.api&&e.api[l]||null;return g?g.permission:null},rulesForCaller:async()=>ce(await a(),e),heldFor:f,accessForCaller:i,checkRoleWrite:(l,g,j)=>we(f(l),e,{before:g||null,after:j||null}),checkGrantWrite:(l,g)=>Ae(f(l),e,g)}}function pr(e,t){let n=t||{},s=Object.assign({wixUsers:zn.default,currentMember:en.currentMember,items:Wn.items,auth:Jn.auth},n.deps||{});return Kn(e,s,n)}function mr(){return{ok:!0,side:"backend",version:Qt}}async function hr(){try{let e=await en.currentMember.getMember();return e&&e._id||null}catch{return null}}0&&(module.exports={ASSIGN_OWNER,CASES,CODES,KIND,PACKAGE_VERSION,PolicyError,SCOPE,SITE,WHEN,abilityFor,abilityFromRules,anonymous,applyClauses,applyGates,assertDeclared,assertGates,backendMemberId,backendPing,can,caseTable,checkGrantRow,checkGrantWrite,checkRoleRow,checkRoleWrite,contains,createAccess,createPrincipal,deny,denyOpaque,filterFor,grantRulesFor,hasRole,heldBy,holdsAt,isDenial,normaliseRoles,ok,parseGates,permissionFor,resolveGrants,resolvePlaceholders,resolveSubjects,resolveWhere,rulesFor,validateCatalogue,validatePolicy,verifyGates});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liquisio/wix-access",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "One authorization policy for Wix, serving the web-method gate, backend, database and page code. Built against measured platform behaviour.",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"types": "./types.d.ts",
|
package/public.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from './types'
|
|
2
|
-
import { Ability, SerialisedRule } from './types'
|
|
2
|
+
import { Ability, SerialisedRule, AccessForCaller, Held, ScopeRef, RoleRow, GrantWrite, Ok, Denial } from './types'
|
|
3
3
|
|
|
4
4
|
export type GuardMode = 'hide' | 'disable' | 'collapse'
|
|
5
5
|
|
|
@@ -10,7 +10,7 @@ export interface FrontendAccessOptions {
|
|
|
10
10
|
* at module scope may not be a function yet, and a missing one makes the kit
|
|
11
11
|
* deny everything rather than throw.
|
|
12
12
|
*/
|
|
13
|
-
fetchRules: () => Promise<SerialisedRule[]>
|
|
13
|
+
fetchRules: () => Promise<SerialisedRule[] | AccessForCaller>
|
|
14
14
|
onError?: (error: unknown) => void
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -28,6 +28,14 @@ export interface FrontendAccess {
|
|
|
28
28
|
/** Why it failed, or null. */
|
|
29
29
|
readonly reason: string | null
|
|
30
30
|
guard(element: unknown, action: string, resource: string, object?: unknown, mode?: GuardMode): boolean
|
|
31
|
+
/** 0.6.0: what the caller holds, from accessForCaller. Empty with the array form. */
|
|
32
|
+
held(): Held[]
|
|
33
|
+
/** 0.6.0: holds the permission anywhere, or over `scope` (which needs its path). */
|
|
34
|
+
holds(permission: string, scope?: ScopeRef): boolean
|
|
35
|
+
/** 0.6.0: the server's role-write check over what was fetched. */
|
|
36
|
+
mayDefineRole(before: RoleRow | null, after: RoleRow | null): Ok<null> | Denial
|
|
37
|
+
/** 0.6.0: the server's grant-write check over what was fetched. A target without a path is refused. */
|
|
38
|
+
mayGrant(input: GrantWrite): Ok<null> | Denial
|
|
31
39
|
apply(element: unknown, allowed: boolean, mode?: GuardMode): boolean
|
|
32
40
|
}
|
|
33
41
|
|
package/public.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var X=Object.defineProperty;var Rt=Object.getOwnPropertyDescriptor;var Tt=Object.getOwnPropertyNames;var Pt=Object.prototype.hasOwnProperty;var kt=(t,e)=>{for(var n in e)X(t,n,{get:e[n],enumerable:!0})},Dt=(t,e,n,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Tt(e))!Pt.call(t,r)&&r!==n&&X(t,r,{get:()=>e[r],enumerable:!(s=Rt(e,r))||s.enumerable});return t};var Lt=t=>Dt(X({},"__esModule",{value:!0}),t);var kn={};kt(kn,{CASES:()=>Ye,CODES:()=>E,KIND:()=>F,PACKAGE_VERSION:()=>Ge,PolicyError:()=>x,SCOPE:()=>$,WHEN:()=>y,abilityFor:()=>$t,abilityFromRules:()=>N,anonymous:()=>Ke,applyClauses:()=>It,applyGates:()=>Ft,assertGates:()=>Nt,can:()=>w,caseTable:()=>Mt,createAccess:()=>Ct,createPrincipal:()=>ne,deny:()=>ee,denyOpaque:()=>He,filterFor:()=>Et,frontendRoleTitles:()=>Pn,hasRole:()=>Qe,isDenial:()=>k,normaliseRoles:()=>te,ok:()=>Ze,parseGates:()=>Be,permissionFor:()=>et,publicPing:()=>Tn,resolvePlaceholders:()=>wt,resolveSubjects:()=>D,resolveWhere:()=>K,rulesFor:()=>T,validatePolicy:()=>Xe,verifyGates:()=>Ve});module.exports=Lt(kn);var _t=require("wix-members-frontend");var E={FORBIDDEN:"FORBIDDEN",UNAUTHENTICATED:"UNAUTHENTICATED",UNVERIFIED:"UNVERIFIED",NOT_FOUND:"NOT_FOUND",INVALID_POLICY:"INVALID_POLICY",INVALID_ARGUMENT:"INVALID_ARGUMENT"},x=class extends Error{constructor(e){super(e),this.name="PolicyError",this.code=E.INVALID_POLICY}};function Ze(t){return{ok:!0,data:t===void 0?null:t}}function ee(t,e,n){let s={ok:!1,code:t||E.FORBIDDEN};return e&&(s.action=e),n&&(s.detail=n),s}var k=t=>!!t&&t.ok===!1;function He(t){return ee(E.NOT_FOUND,t)}var F={VISITOR:"visitor",MEMBER:"member",CAPABILITY:"capability",SERVICE:"service"};function te(t){if(!Array.isArray(t))return[];let e=[];for(let n of t){if(typeof n=="string"){e.push(n);continue}if(!n||typeof n!="object")continue;let s=n.title||n.name||n.roleKey;s&&e.push(s)}return e}function ne(t){let e=t||{},n=e.memberId||null,s=te(e.roles);return{kind:e.kind||(n?F.MEMBER:F.VISITOR),memberId:n,roles:s,subjects:Array.isArray(e.subjects)?e.subjects.slice():[],domain:e.domain&&typeof e.domain=="object"?e.domain:{},unverified:!!e.unverified}}var Ke=()=>ne({kind:F.VISITOR}),Qe=(t,e)=>t.roles.indexOf(e)!==-1;var y={ANYONE:"anyone",ANONYMOUS:"anonymous",MEMBER:"member"},m=t=>!!t&&typeof t=="object"&&!Array.isArray(t),Ut=t=>Array.isArray(t)?t:[t];function f(t,e){throw new x("policy"+t+": "+e)}function qt(t,e){let n=".subjects."+t;m(e)||f(n,"must be an object");let r=["when","role","domain"].filter(o=>e[o]!==void 0);if(r.length===0&&f(n,'needs exactly one of when/role/domain \u2014 "{}" is ambiguous between a visitor and a member'),r.length>1&&f(n,"has "+r.join(" and ")+"; use exactly one"),e.when!==void 0){let o=[y.ANYONE,y.ANONYMOUS,y.MEMBER];o.indexOf(e.when)===-1&&f(n+".when","must be one of "+o.join(", ")+" (got "+JSON.stringify(e.when)+")")}e.role!==void 0&&typeof e.role!="string"&&f(n+".role","must be a string"),e.domain!==void 0&&typeof e.domain!="string"&&f(n+".domain","must be a string")}function zt(t,e,n){let s=".rules["+e+"]";m(t)||f(s,"must be an object"),typeof t.subject!="string"&&f(s+".subject","must be a string"),n.indexOf(t.subject)===-1&&f(s+".subject",'"'+t.subject+'" is not declared in policy.subjects'),t.actions===void 0&&f(s+".actions","is required");for(let r of Ut(t.actions))typeof r!="string"&&f(s+".actions","must be a string or an array of strings");typeof t.resource!="string"&&f(s+".resource","must be a string"),t.where!==void 0&&!m(t.where)&&f(s+".where","must be an object")}var We=["Anyone","SiteMember","Admin"];function Bt(t,e,n){let s=".api."+t;m(e)||f(s,"must be an object"),We.indexOf(e.permission)===-1&&f(s+".permission","must be one of "+We.join(", ")+" (got "+JSON.stringify(e.permission)+")"),e.ability!==void 0&&((!Array.isArray(e.ability)||e.ability.length!==2)&&f(s+".ability","must be [action, resource]"),(typeof e.ability[0]!="string"||typeof e.ability[1]!="string")&&f(s+".ability","both entries must be strings")),e.subject!==void 0&&n.indexOf(e.subject)===-1&&f(s+".subject",'"'+e.subject+'" is not declared in policy.subjects')}var Vt=["resource","owner","actor","tenant","profile"];function Gt(t,e){let n=".collections."+t;m(e)||f(n,"must be an object");for(let s of Vt)e[s]!==void 0&&(typeof e[s]!="string"||!e[s])&&f(n+"."+s,"must be a non-empty string");e.owner!==void 0&&e.owner===e.actor&&f(n,'owner and actor must be different fields (both are "'+e.owner+'")')}function Xe(t){if(!m(t))throw new x("policy must be an object");m(t.subjects)||f(".subjects","is required and must be an object");let e=Object.keys(t.subjects);e.length===0&&f(".subjects","declares no subjects");for(let n of e)qt(n,t.subjects[n]);if(Array.isArray(t.rules)||f(".rules","is required and must be an array"),t.rules.forEach((n,s)=>zt(n,s,e)),t.api!==void 0){m(t.api)||f(".api","must be an object");for(let n of Object.keys(t.api))Bt(n,t.api[n],e)}if(t.collections!==void 0){m(t.collections)||f(".collections","must be an object");for(let n of Object.keys(t.collections))Gt(n,t.collections[n])}return t}function D(t,e){let n=new Set(t.subjects||[]);for(let s of Object.keys(e.subjects)){let r=e.subjects[s];(r.when===y.ANYONE||r.when===y.ANONYMOUS&&!t.memberId||r.when===y.MEMBER&&t.memberId||r.role!==void 0&&t.roles.indexOf(r.role)!==-1||r.domain!==void 0&&t.domain[r.domain])&&n.add(s)}return Array.from(n)}function et(t,e){let n=t.api&&t.api[e];return n?n.permission:null}var L=class{constructor(e,n){this.operator=e,this.value=n,Object.defineProperty(this,"t",{writable:!0})}get notes(){return this.t}addNote(e){this.t=this.t||[],this.t.push(e)}},M=class extends L{},O=class extends M{constructor(e,n){if(!Array.isArray(n))throw new Error(`"${e}" operator expects to receive an array of conditions`);super(e,n)}},b="__itself__",j=class extends L{constructor(e,n,s){super(e,s),this.field=n}},ie=new M("__null__",null),oe=Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);function Yt(t,e){return e instanceof O&&e.operator===t}function ae(t,e){return e.length===1?e[0]:new O(t,(function n(s,r,o){let i=o||[];for(let a=0,u=r.length;a<u;a++){let l=r[a];Yt(s,l)?n(s,l.value,i):i.push(l)}return i})(t,e))}var Jt=t=>t,tt=()=>Object.create(null),nt=Object.defineProperty(tt(),"__@type@__",{value:"ignore value"});function Zt(t,e,n=!1){if(!t||t&&t.constructor!==Object)return!1;for(let s in t)if(oe(t,s)&&oe(e,s)&&(!n||t[s]!==nt))return!0;return!1}function Ht(t){let e=[];for(let n in t)oe(t,n)&&t[n]!==nt&&e.push(n);return e}function se(t,e){e!==ie&&t.push(e)}var ce=t=>ae("and",t);var U={compound(t,e,n){let s=(Array.isArray(e)?e:[e]).map(r=>n.parse(r));return new O(t.name,s)},field:(t,e,n)=>new j(t.name,n.field,e),document:(t,e)=>new M(t.name,e)},S=class{constructor(e,n=tt()){this.o=void 0,this.s=void 0,this.i=void 0,this.u=void 0,this.h=void 0,this.parse=this.parse.bind(this),this.u={operatorToConditionName:n.operatorToConditionName||Jt,defaultOperatorName:n.defaultOperatorName||"eq",mergeFinalConditions:n.mergeFinalConditions||ce},this.o=Object.keys(e).reduce((s,r)=>(s[r]=Object.assign({name:this.u.operatorToConditionName(r)},e[r]),s),{}),this.s=Object.assign({},n.fieldContext,{field:"",query:{},parse:this.parse,hasOperators:s=>Zt(s,this.o,n.useIgnoreValue)}),this.i=Object.assign({},n.documentContext,{parse:this.parse,query:{}}),this.h=n.useIgnoreValue?Ht:Object.keys}setParse(e){this.parse=e,this.s.parse=e,this.i.parse=e}parseField(e,n,s,r){let o=this.o[n];if(!o)throw new Error(`Unsupported operator "${n}"`);if(o.type!=="field")throw new Error(`Unexpected ${o.type} operator "${n}" at field level`);return this.s.field=e,this.s.query=r,this.parseInstruction(o,s,this.s)}parseInstruction(e,n,s){return typeof e.validate=="function"&&e.validate(e,n),(e.parse||U[e.type])(e,n,s)}parseFieldOperators(e,n){let s=[],r=this.h(n);for(let o=0,i=r.length;o<i;o++){let a=r[o];if(!this.o[a])throw new Error(`Field query for "${e}" may contain only operators or a plain object as a value`);se(s,this.parseField(e,a,n[a],n))}return s}parse(e){let n=[],s=this.h(e);this.i.query=e;for(let r=0,o=s.length;r<o;r++){let i=s[r],a=e[i],u=this.o[i];if(u){if(u.type!=="document"&&u.type!=="compound")throw new Error(`Cannot use parsing instruction for operator "${i}" in "document" context as it is supposed to be used in "${u.type}" context`);se(n,this.parseInstruction(u,a,this.i))}else this.s.hasOperators(a)?n.push(...this.parseFieldOperators(i,a)):se(n,this.parseField(i,this.u.defaultOperatorName,a,e))}return this.u.mergeFinalConditions(n)}};function re(t,e){let n=t[e];if(typeof n!="function")throw new Error(`Unable to interpret "${e}" condition. Did you forget to register interpreter for it?`);return n}function Kt(t){return t.operator}function st(t,e){let n=e,s=n&&n.getInterpreterName||Kt,r;switch(n?n.numberOfArguments:0){case 1:r=i=>{let a=s(i,n);return re(t,a)(i,o)};break;case 3:r=(i,a,u)=>{let l=s(i,n);return re(t,l)(i,a,u,o)};break;default:r=(i,a)=>{let u=s(i,n);return re(t,u)(i,a,o)}}let o=Object.assign({},n,{interpret:r});return o.interpret}function rt(t,e){return(n,...s)=>{let r=t(n,...s),o=e.bind(null,r);return o.ast=r,o}}var Gn=S.prototype.parseInstruction;function ot(t,e){if(!Array.isArray(e))throw new Error(`"${t.name}" expects value to be an array`)}function it(t,e){if(ot(t,e),!e.length)throw new Error(`"${t.name}" expects to have at least one element in array`)}var ue=t=>(e,n)=>{if(typeof n!==t)throw new Error(`"${e.name}" expects value to be a "${t}"`)},at={type:"compound",validate:it,parse(t,e,{parse:n}){let s=e.map(r=>n(r));return ae(t.name,s)}},Qt=at,Wt={type:"compound",validate:it},Xt={type:"field",validate(t,e){if(!(e&&(e instanceof RegExp||e.constructor===Object)))throw new Error(`"${t.name}" expects to receive either regular expression or object of field operators`)},parse(t,e,n){let s=e instanceof RegExp?new j("regex",n.field,e):n.parse(e,n);return new O(t.name,[s])}},le={type:"field",validate(t,e){if(!e||e.constructor!==Object)throw new Error(`"${t.name}" expects to receive an object with nested query or field level operators`)},parse(t,e,{parse:n,field:s,hasOperators:r}){let o=r(e)?n(e,{field:b}):n(e);return new j(t.name,s,o)}},fe={type:"field",validate:ue("number")},C={type:"field",validate:ot},pe=C,de=C,en={type:"field",validate(t,e){if(!Array.isArray(e)||e.length!==2)throw new Error(`"${t.name}" expects an array with 2 numeric elements`)}},he={type:"field",validate:ue("boolean")},z={type:"field",validate:function(t,e){if(!(typeof e=="string"||typeof e=="number"||e instanceof Date))throw new Error(`"${t.name}" expects value to be comparable (i.e., string, number or date)`)}},_=z,me=_,ye=_,B={type:"field"},be=B,ge={type:"field",validate(t,e){if(!(e instanceof RegExp)&&typeof e!="string")throw new Error(`"${t.name}" expects value to be a regular expression or a string that represents regular expression`)},parse(t,e,n){let s=typeof e=="string"?new RegExp(e,n.query.$options||""):e;return new j(t.name,n.field,s)}},xe={type:"field",parse:()=>ie},tn={type:"document",validate:ue("function")},nn=Object.freeze({__proto__:null,$and:at,$or:Qt,$nor:Wt,$not:Xt,$elemMatch:le,$size:fe,$in:C,$nin:pe,$all:de,$mod:en,$exists:he,$gte:z,$gt:_,$lt:me,$lte:ye,$eq:B,$ne:be,$regex:ge,$options:xe,$where:tn}),q=class extends S{constructor(e){super(e,{defaultOperatorName:"$eq",operatorToConditionName:n=>n.slice(1)})}parse(e,n){return n&&n.field?ce(this.parseFieldOperators(n.field,e)):super.parse(e)}},V=nn;function Oe(t,e,n){for(let s=0,r=t.length;s<r;s++)if(n(t[s],e)===0)return!0;return!1}function je(t,e){return Array.isArray(t)&&Number.isNaN(Number(e))}function ct(t,e,n){if(!je(t,e))return n(t,e);let s=[];for(let r=0;r<t.length;r++){let o=n(t[r],e);o!==void 0&&(s=s.concat(o))}return s}function v(t){return(e,n,s)=>{let r=s.get(n,e.field);return Array.isArray(r)?r.some(o=>t(e,o,s)):t(e,r,s)}}var sn=Object.hasOwn||Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty),rn=(t,e)=>t[e];function ut(t,e,n){let s=e.lastIndexOf(".");return s===-1?[t,e]:[n(t,e.slice(0,s)),e.slice(s+1)]}function on(t,e,n=rn){if(e===b)return t;if(!t)throw new Error(`Unable to get field "${e}" out of ${String(t)}.`);return(function(s,r,o){if(r.indexOf(".")===-1)return ct(s,r,o);let i=r.split("."),a=s;for(let u=0,l=i.length;u<l;u++)if(a=ct(a,i[u],o),!a||typeof a!="object")return u<l-1?void 0:a;return a})(t,e,n)}function ve(t,e){return t===e?0:t>e?1:-1}function we(t,e={}){return st(t,Object.assign({get:on,compare:ve},e))}var lt=(t,e,{interpret:n})=>t.value.some(s=>n(s,e)),an=(t,e,n)=>!lt(t,e,n),$e=(t,e,{interpret:n})=>t.value.every(s=>n(s,e)),cn=(t,e,{interpret:n})=>!n(t.value[0],e),G=(t,e,{compare:n,get:s})=>{let r=s(e,t.field);return Array.isArray(r)&&!Array.isArray(t.value)?Oe(r,t.value,n):n(r,t.value)===0},Ae=(t,e,n)=>!G(t,e,n),Ee=v((t,e,n)=>{let s=n.compare(e,t.value);return s===0||s===-1}),Ie=v((t,e,n)=>n.compare(e,t.value)===-1),Ne=v((t,e,n)=>n.compare(e,t.value)===1),Fe=v((t,e,n)=>{let s=n.compare(e,t.value);return s===0||s===1}),Me=(t,e,{get:n})=>{if(t.field===b)return e!==void 0;let[s,r]=ut(e,t.field,n),o=i=>i==null?!!i===t.value:sn(i,r)===t.value;return je(s,r)?s.some(o):o(s)},un=v((t,e)=>typeof e=="number"&&e%t.value[0]===t.value[1]),Se=(t,e,{get:n})=>{let[s,r]=ut(e,t.field,n),o=i=>{let a=n(i,r);return Array.isArray(a)&&a.length===t.value};return t.field!==b&&je(s,r)?s.some(o):o(s)},Ce=v((t,e)=>typeof e=="string"&&t.value.test(e)),R=v((t,e,{compare:n})=>Oe(t.value,e,n)),_e=(t,e,n)=>!R(t,e,n),Re=(t,e,{compare:n,get:s})=>{let r=s(e,t.field);return Array.isArray(r)&&t.value.every(o=>Oe(r,o,n))},Te=(t,e,{interpret:n,get:s})=>{let r=s(e,t.field);return Array.isArray(r)&&r.some(o=>n(t.value,o))},ln=(t,e)=>t.value.call(e),fn=Object.freeze({__proto__:null,or:lt,nor:an,and:$e,not:cn,eq:G,ne:Ae,lte:Ee,lt:Ie,gt:Ne,gte:Fe,exists:Me,mod:un,size:Se,regex:Ce,within:R,nin:_e,all:Re,elemMatch:Te,where:ln}),Y=Object.assign({},fn,{in:R}),Qn=we(Y);function ft(t){return t===null||typeof t!="object"?t:t instanceof Date?t.getTime():t&&typeof t.toJSON=="function"?t.toJSON():t}var pn=(t,e)=>ve(ft(t),ft(e));function J(t,e,n){let s=new q(t),r=we(e,Object.assign({compare:pn},n));if(n&&n.forPrimitives){let o={field:b},i=s.parse;s.setParse(a=>i(a,o))}return rt(s.parse,r)}var ns=J(V,Y),ss=J(["$and","$or"].reduce((t,e)=>(t[e]=Object.assign({},t[e],{type:"field"}),t),Object.assign({},V,{$nor:Object.assign({},V.$nor,{type:"field",parse:U.compound})})),Y,{forPrimitives:!0});var bt=Object.hasOwn||((t,e)=>Object.prototype.hasOwnProperty.call(t,e));function Pe(t){return Array.isArray(t)?t:[t]}var I="__caslSubjectType__";function gt(t,e){if(e){if(!bt(e,I))Object.defineProperty(e,I,{value:t});else if(t!==e[I])throw new Error(`Trying to cast object to subject type ${t} but previously it was casted to ${e[I]}`)}return e}var H=t=>{let e=typeof t;return e==="string"||e==="function"},xt=t=>t.modelName||t.name;function dn(t){return typeof t=="string"?t:xt(t)}function Ot(t){return bt(t,I)?t[I]:xt(t.constructor)}var pt={function:t=>t.constructor,string:Ot};function dt(t,e,n){for(let s=n;s<e.length;s++)t.push(e[s])}function ht(t,e){if(!t||!t.length)return e||[];if(!e||!e.length)return t||[];let n=0,s=0,r=[];for(;n<t.length&&s<e.length;)t[n].priority<e[s].priority?(r.push(t[n]),n++):t[n].priority>e[s].priority?(r.push(e[s]),s++):(r.push(t[n]),n++,s++);return dt(r,t,n),dt(r,e,s),r}function Z(t,e,n){let s=t.get(e);return s||(s=n(),t.set(e,s)),s}var hn=t=>t;function mn(t,e){let n;for(let s=0;s<t.length;s++){let r=e(t[s]);n&&r&&n.push(t[s]),r||(n??(n=t.slice(0,s)))}return n||t}function yn(t,e){if(Array.isArray(t.fields)&&!t.fields.length)throw new Error("`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa");if(t.fields&&!e.fieldMatcher)throw new Error('You need to pass "fieldMatcher" option in order to restrict access by fields');if(t.conditions&&!e.conditionsMatcher)throw new Error('You need to pass "conditionsMatcher" option in order to restrict access by conditions')}var ke=class{constructor(e,n,s=0){yn(e,n),this.action=n.resolveAction(e.action),this.subject=e.subject,this.inverted=!!e.inverted,this.conditions=e.conditions,this.reason=e.reason,this.origin=e,this.fields=e.fields?Pe(e.fields):void 0,this.priority=s,this.t=n}i(){return this.conditions&&!this.o&&(this.o=this.t.conditionsMatcher(this.conditions)),this.o}get ast(){let e=this.i();return e?e.ast:void 0}matchesConditions(e){return this.conditions?!e||H(e)?!this.inverted:this.i()(e):!0}matchesField(e){return this.fields?e?(this.u||(this.u=this.t.fieldMatcher(this.fields)),this.u(e)):!this.inverted:!0}};function bn(t,e){let n={value:t,prev:e,next:null};return e&&(e.next=n),n}function gn(t){t.next&&(t.next.prev=t.prev),t.prev&&(t.prev.next=t.next),t.next=t.prev=null}var mt=()=>({rules:[],merged:!1}),yt=()=>new Map,De=class{constructor(e=[],n={}){this.h=!1,this.l=new Map,this.p={conditionsMatcher:n.conditionsMatcher,fieldMatcher:n.fieldMatcher,resolveAction:n.resolveAction||hn},this.$=n.anyAction||"manage",this.A=n.anySubjectType||"all",this.m=e,this.M=!!n.detectSubjectType,this.j=n.detectSubjectType||Ot,this.v(e)}get rules(){return this.m}detectSubjectType(e){return H(e)?e:e?this.j(e):this.A}update(e){let n={rules:e,ability:this,target:this};return this._("update",n),this.m=e,this.v(e),this._("updated",n),this}v(e){let n=new Map,s;for(let r=e.length-1;r>=0;r--){let o=e.length-r-1,i=new ke(e[r],this.p,o),a=Pe(i.action),u=Pe(i.subject||this.A);!this.h&&i.fields&&(this.h=!0);for(let l=0;l<u.length;l++){let h=Z(n,u[l],yt);s===void 0&&(s=typeof u[l]),typeof u[l]!==s&&s!=="mixed"&&(s="mixed");for(let A=0;A<a.length;A++)Z(h,a[A],mt).rules.push(i)}}if(this.l=n,s!=="mixed"&&!this.M){let r=pt[s]||pt.string;this.j=r}}possibleRulesFor(e,n=this.A){if(!H(n))throw new Error('"possibleRulesFor" accepts only subject types (i.e., string or class) as the 2nd parameter');let s=Z(this.l,n,yt),r=Z(s,e,mt);if(r.merged)return r.rules;let o=e!==this.$&&s.has(this.$)?s.get(this.$).rules:void 0,i=ht(r.rules,o);return n!==this.A&&(i=ht(i,this.possibleRulesFor(e,this.A))),r.rules=i,r.merged=!0,i}rulesFor(e,n,s){let r=this.possibleRulesFor(e,n);if(s&&typeof s!="string")throw new Error("The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details");return this.h?mn(r,o=>o.matchesField(s)):r}actionsFor(e){if(!H(e))throw new Error('"actionsFor" accepts only subject types (i.e., string or class) as a parameter');let n=new Set,s=this.l.get(e);s&&Array.from(s.keys()).forEach(o=>n.add(o));let r=e!==this.A?this.l.get(this.A):void 0;return r&&Array.from(r.keys()).forEach(o=>n.add(o)),Array.from(n)}on(e,n){this.F=this.F||new Map;let s=this.F,r=s.get(e)||null,o=bn(n,r);return s.set(e,o),()=>{let i=s.get(e);!o.next&&!o.prev&&i===o?s.delete(e):o===i&&s.set(e,o.prev),gn(o)}}_(e,n){if(!this.F)return;let s=this.F.get(e)||null,r=[];for(;s!==null;)r.push(s.value),s=s.prev;for(let o=0;o<r.length;o++)r[o](n)}},Le=class extends De{can(e,n,s){let r=this.relevantRuleFor(e,n,s);return!!r&&!r.inverted}relevantRuleFor(e,n,s){let r=this.detectSubjectType(n),o=this.rulesFor(e,r,s);for(let i=0,a=o.length;i<a;i++)if(o[i].matchesConditions(n))return o[i];return null}cannot(e,n,s){return!this.can(e,n,s)}},xn={$eq:B,$ne:be,$lt:me,$lte:ye,$gt:_,$gte:z,$in:C,$nin:pe,$all:de,$size:fe,$regex:ge,$options:xe,$elemMatch:le,$exists:he},On={eq:G,ne:Ae,lt:Ie,lte:Ee,gt:Ne,gte:Fe,in:R,nin:_e,all:Re,size:Se,regex:Ce,elemMatch:Te,exists:Me,and:$e};var jn=J(xn,On),vn=/[-/\\^$+?.()|[\]{}]/g,wn=/\.?\*+\.?/g,$n=/\*+/,An=/\./g;function En(t,e,n){let s=n[0]==="*"||t[0]==="."&&t[t.length-1]==="."?"+":"*",r=t.indexOf("**")===-1?"[^.]":".",o=t.replace(An,"\\$&").replace($n,r+s);return e+t.length===n.length?`(?:${o})?`:o}function In(t,e,n){return t==="."&&(n[e-1]==="*"||n[e+1]==="*")?t:`\\${t}`}function Nn(t){let e=t.map(s=>s.replace(vn,In).replace(wn,En)),n=e.length>1?`(?:${e.join("|")})`:e[0];return new RegExp(`^${n}$`)}var Fn=t=>{let e;return n=>(typeof e>"u"&&(e=t.every(s=>s.indexOf("*")===-1)?null:Nn(t)),e===null?t.indexOf(n)!==-1:e.test(n))};function jt(t=[],e={}){return new Le(t,Object.assign({conditionsMatcher:jn,fieldMatcher:Fn},e))}var Mn=t=>`Cannot execute "${t.action}" on "${t.subjectType}"`,vt=function(e){this.message=e};vt.prototype=Object.create(Error.prototype);var Ue=class extends vt{static setDefaultMessage(e){this.P=typeof e=="string"?()=>e:e}static from(e){return new this(e)}constructor(e){super(""),this.ability=e,typeof Error.captureStackTrace=="function"&&(this.name="ForbiddenError",Error.captureStackTrace(this,this.constructor))}setMessage(e){return this.message=e,this}throwUnlessCan(e,n,s){let r=this.unlessCan(e,n,s);if(r)throw r}unlessCan(e,n,s){let r=this.ability.relevantRuleFor(e,n,s);if(r&&!r.inverted)return;this.action=e,this.subject=n,this.subjectType=dn(this.ability.detectSubjectType(n)),this.field=s;let o=r?r.reason:"";return this.message=this.message||o||this.constructor.P(this),this}};Ue.P=Mn;var us=Object.freeze({__proto__:null});function qe(t,e,n){if(t==null)return t;if(typeof t=="string"){if(t.indexOf("$principal.")!==0)return t;let r=t.slice(11).split(".").reduce((o,i)=>o==null?o:o[i],e);return r==null&&(n.unresolved=!0),r}if(Array.isArray(t))return t.map(s=>qe(s,e,n));if(typeof t=="object"){let s={};for(let r of Object.keys(t))s[r]=qe(t[r],e,n);return s}return t}function K(t,e){let n={unresolved:!1};return{conditions:qe(t,e,n),unresolved:n.unresolved}}function wt(t,e){return K(t,e).conditions}function T(t,e){let n=D(t,e),s=[];for(let r of e.rules){if(n.indexOf(r.subject)===-1)continue;let o={action:r.actions,subject:r.resource};if(r.where){let{conditions:i,unresolved:a}=K(r.where,t);if(a)continue;o.conditions=i}s.push(o)}return s}function N(t){return jt(Array.isArray(t)?t:[])}function $t(t,e){return N(T(t,e))}function w(t,e,n,s){return s==null?t.can(e,n):t.can(e,gt(n,Object.assign({},s)))}var $={ALL:"all",NONE:"none",FIELDS:"fields",AMBIGUOUS:"ambiguous"},At={$in:"in",$nin:"nin",$ne:"ne",$gt:"gt",$gte:"gte",$lt:"lt",$lte:"lte"};function Sn(t){let e=[];for(let n of Object.keys(t)){let s=t[n];if(s===null||typeof s!="object"||Array.isArray(s)){e.push({field:n,op:"eq",value:s});continue}let r=Object.keys(s);if(r.length!==1||!At[r[0]])return null;e.push({field:n,op:At[r[0]],value:s[r[0]]})}return e}var Cn=(t,e)=>t==="manage"||t===e||Array.isArray(t)&&(t.indexOf(e)!==-1||t.indexOf("manage")!==-1),_n=(t,e)=>t==="all"||t===e;function Et(t,e,n,s){let r=T(t,e).filter(i=>Cn(i.action,n)&&_n(i.subject,s));if(r.length===0)return{scope:$.NONE,clauses:[]};if(r.some(i=>!i.conditions))return{scope:$.ALL,clauses:[]};if(r.length>1)return{scope:$.AMBIGUOUS,clauses:[]};let o=Sn(r[0].conditions);return o?{scope:$.FIELDS,clauses:o}:{scope:$.AMBIGUOUS,clauses:[]}}function It(t,e){let n=t;for(let s of e)s.op==="in"?n=n.hasSome(s.field,s.value):s.op==="nin"?n=n.not(n.hasSome(s.field,s.value)):n=n[s.op](s.field,s.value);return n}var ze=/export\s+const\s+([A-Za-z0-9_$]+)\s*=\s*webMethod\s*\(\s*Permissions\s*\.\s*([A-Za-z0-9_$]+)/g,Rn=[[/export\s*{\s*[A-Za-z0-9_$,\s]+}/,"export { x } \u2014 the call and the export must be one statement"],[/export\s+const\s+[A-Za-z0-9_$]+\s*=\s*webMethod\s*\(\s*Permissions\s*\[/,"Permissions['X'] \u2014 the property must be dotted and literal"],[/export\s+const\s+[A-Za-z0-9_$]+\s*=\s*webMethod\s*\(\s*[A-Za-z0-9_$]+\s*\(/,"a computed permission \u2014 it must be written out as Permissions.LEVEL"]];function Be(t){let e={},n=String(t||"");ze.lastIndex=0;let s=ze.exec(n);for(;s;)e[s[1]]=s[2],s=ze.exec(n);return e}function Ve(t,e,n){let s=n||{},r=e&&e.api||{},o=Be(t),i=String(t||""),a=[],u=[];for(let p of Object.keys(o)){let c=r[p];c?c.permission!==o[p]&&a.push({name:p,declared:c.permission,written:o[p]}):u.push({name:p,gate:o[p]})}let l=s.complete?Object.keys(r).filter(p=>!(p in o)):[],h=[];for(let[p,c]of Rn)p.test(i)&&h.push(c);return{ok:a.length+u.length+l.length+h.length===0,found:o,mismatched:a,undeclared:u,missing:l,suspect:h}}function Nt(t,e,n){let s=Ve(t,e,n);if(s.ok)return!0;let r=[];for(let o of s.mismatched)r.push(o.name+": policy says "+o.declared+", the export says "+o.written);for(let o of s.undeclared)r.push(o.name+": gated "+o.gate+" but missing from policy.api");for(let o of s.missing)r.push(o+": declared in policy.api but not exported here");for(let o of s.suspect)r.push("unreachable export shape \u2014 "+o);throw new Error(`wix-access: web-method gates do not match the policy:
|
|
1
|
+
var ve=Object.defineProperty;var Os=Object.getOwnPropertyDescriptor;var As=Object.getOwnPropertyNames;var js=Object.prototype.hasOwnProperty;var ws=(e,t)=>{for(var s in t)ve(e,s,{get:t[s],enumerable:!0})},xs=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of As(t))!js.call(e,r)&&r!==s&&ve(e,r,{get:()=>t[r],enumerable:!(n=Os(t,r))||n.enumerable});return e};var vs=e=>xs(ve({},"__esModule",{value:!0}),e);var Dn={};ws(Dn,{CASES:()=>wt,CODES:()=>b,KIND:()=>Z,PACKAGE_VERSION:()=>jt,PolicyError:()=>R,SCOPE:()=>F,SITE:()=>x,WHEN:()=>M,abilityFor:()=>ts,abilityFromRules:()=>J,anonymous:()=>vt,applyClauses:()=>os,applyGates:()=>as,assertGates:()=>is,can:()=>B,caseTable:()=>ds,checkGrantRow:()=>At,checkGrantWrite:()=>xe,checkRoleRow:()=>Ot,checkRoleWrite:()=>we,contains:()=>gt,createAccess:()=>ms,createPrincipal:()=>Ie,deny:()=>A,denyOpaque:()=>xt,filterFor:()=>rs,frontendRoleTitles:()=>Cn,grantRulesFor:()=>Ae,hasRole:()=>Et,heldBy:()=>us,holdsAt:()=>T,isDenial:()=>re,normaliseRoles:()=>Ee,ok:()=>Y,parseGates:()=>mt,permissionFor:()=>kt,publicPing:()=>Mn,resolveGrants:()=>es,resolvePlaceholders:()=>dt,resolveSubjects:()=>ae,resolveWhere:()=>U,rulesFor:()=>se,validateCatalogue:()=>ie,validatePolicy:()=>Nt,verifyGates:()=>yt});module.exports=vs(Dn);var ys=require("wix-members-frontend");var b={FORBIDDEN:"FORBIDDEN",UNAUTHENTICATED:"UNAUTHENTICATED",UNVERIFIED:"UNVERIFIED",NOT_FOUND:"NOT_FOUND",INVALID_POLICY:"INVALID_POLICY",INVALID_ARGUMENT:"INVALID_ARGUMENT"},R=class extends Error{constructor(t){super(t),this.name="PolicyError",this.code=b.INVALID_POLICY}};function Y(e){return{ok:!0,data:e===void 0?null:e}}function A(e,t,s){let n={ok:!1,code:e||b.FORBIDDEN};return t&&(n.action=t),s&&(n.detail=s),n}var re=e=>!!e&&e.ok===!1;function xt(e){return A(b.NOT_FOUND,e)}var Z={VISITOR:"visitor",MEMBER:"member",CAPABILITY:"capability",SERVICE:"service"};function Ee(e){if(!Array.isArray(e))return[];let t=[];for(let s of e){if(typeof s=="string"){t.push(s);continue}if(!s||typeof s!="object")continue;let n=s.title||s.name||s.roleKey;n&&t.push(n)}return t}function Ie(e){let t=e||{},s=t.memberId||null,n=Ee(t.roles);return{kind:t.kind||(s?Z.MEMBER:Z.VISITOR),memberId:s,roles:n,subjects:Array.isArray(t.subjects)?t.subjects.slice():[],domain:t.domain&&typeof t.domain=="object"?t.domain:{},unverified:!!t.unverified,grants:Array.isArray(t.grants)?t.grants.slice():[]}}var vt=()=>Ie({kind:Z.VISITOR}),Et=(e,t)=>e.roles.indexOf(t)!==-1;var x="site",Es=/^[a-z][a-z0-9]*([._-][a-z0-9]+)*$/,Is="read",$=e=>!!e&&typeof e=="object"&&!Array.isArray(e),$s=e=>Array.isArray(e)?e:[e],oe=(e,t)=>!!e&&Object.prototype.hasOwnProperty.call(e,t);function d(e,t){throw new R("policy.catalogue"+e+": "+t)}function It(e,t){let s=e.collections&&e.collections[t];return s?s.resource||t:null}function Ns(e,t){let s=[],n=e.collections||{};for(let r of Object.keys(n)){let o=n[r];!$(o)||!o.tenant||(o.resource||r)===t&&s.indexOf(o.tenant)===-1&&s.push(o.tenant)}return s}var _=(e,t)=>typeof t=="string"&&$(e)&&oe(e.permissions,t);function ks(e,t,s,n){let r=s,o=!1;return $(s)&&((Object.keys(s).sort().join(",")!=="kind,upward"||s.upward!==!0)&&d(e+".scope."+t,"must be a scope kind, or { kind, upward: true }"),r=s.kind,o=!0),(typeof r!="string"||!r)&&d(e+".scope."+t,"must be a scope kind, or { kind, upward: true }"),n.indexOf(r)===-1&&d(e+".scope."+t,'"'+r+'" is not in catalogue.scopes ('+n.join(", ")+")"),o}function Rs(e,t,s,n,r){let o=".permissions."+s+".rules["+r+"]";$(n)||d(o,"must be an object"),n.subject!==void 0&&d(o+".subject","a catalogue rule names no subject: its holders come from grants");let i=$s(n.actions);(n.actions===void 0||i.length===0)&&d(o+".actions","is required");for(let a of i)(typeof a!="string"||!a)&&d(o+".actions","must be a string or an array of strings"),a==="manage"&&d(o+".actions",'"manage" is not allowed in a catalogue rule: name the actions');(typeof n.resource!="string"||!n.resource)&&d(o+".resource","must be a string"),n.resource==="all"&&d(o+".resource",'"all" is not allowed: name a resource'),n.where!==void 0&&!$(n.where)&&d(o+".where","must be an object");let c=i.some(a=>a!==Is);if(n.scope===void 0&&d(o+".scope",'is required: "any", or a map of row field to scope kind'),n.scope==="any"){c&&d(o+".scope",'"any" is only for read rules; a rule that writes must be placed by a scope map');return}(!$(n.scope)||Object.keys(n.scope).length===0)&&d(o+".scope",'must be "any" or a non-empty map of row field to scope kind');let u=0;for(let a of Object.keys(n.scope))ks(o,a,n.scope[a],t)||(u+=1);if(u===0&&d(o+".scope","has only upward fields; it needs at least one plain field, so it never reaches above its grant"),n.where)for(let a of Object.keys(n.where))oe(n.scope,a)&&d(o+".where."+a,'repeats the scope field "'+a+'"');if(c)for(let a of Ns(e,n.resource))oe(n.scope,a)||d(o+".scope","writes "+n.resource+', whose collection declares tenant field "'+a+'": pin it in the scope (plain or upward), so a write cannot move the row out of the grant')}function Ss(e,t){let s=t.store;$(s)||d(".store","must be an object { roles, grants }");let n=e.collections||{};for(let a of["roles","grants"]){let f=s[a];(typeof f!="string"||!oe(n,f))&&d(".store."+a,JSON.stringify(f)+" is not a key of policy.collections");for(let p of["owner","actor"])n[f][p]!==void 0&&d(".store."+a,'collection "'+f+'" declares '+p+': "'+n[f][p]+`". The gateway would stamp it with the writer's member id; a store collection declares no `+p)}s.roles===s.grants&&d(".store",'roles and grants name the same collection "'+s.roles+'"');let r=It(e,s.roles),o=It(e,s.grants);r===o&&d(".store",'the roles and grants collections share the resource "'+r+'"');let i=t.gates,c=a=>t.permissions[a].rules.map(f=>f.resource);if(i.roles!==i.grants){let a=[["roles",i.roles,r],["grants",i.grants,o]];for(let[f,p,h]of a)c(p).forEach((g,O)=>{g!==h&&d(".permissions."+p+".rules["+O+"].resource",'"'+g+'" is not the '+f+` collection's resource "`+h+'" (catalogue.gates.'+f+' is "'+p+'")')});return}let u=c(i.roles);u.forEach((a,f)=>{a!==r&&a!==o&&d(".permissions."+i.roles+".rules["+f+"].resource",'"'+a+'" is neither store resource ("'+r+'", "'+o+'")')});for(let a of[r,o])u.indexOf(a)===-1&&d(".gates",'the permission "'+i.roles+'" gates both writes but no rule of it names "'+a+'"')}function ie(e){let t=e.catalogue;$(t)||d("","must be an object");let s=t.scopes;(!Array.isArray(s)||s.length===0)&&d(".scopes","must be a non-empty array of scope kinds, outermost first");let n=[];s.forEach((r,o)=>{(typeof r!="string"||!r)&&d(".scopes["+o+"]","must be a non-empty string"),r===x&&d(".scopes["+o+"]",'"site" is reserved: it is implicit and contains everything'),n.indexOf(r)!==-1&&d(".scopes",'names "'+r+'" twice'),n.push(r)}),t.roleOwner!==void 0&&t.roleOwner!==s[0]&&d(".roleOwner",'must be scopes[0] ("'+s[0]+`"), the outermost kind, so an owner's path is { [roleOwner]: id }`),(!$(t.permissions)||Object.keys(t.permissions).length===0)&&d(".permissions","must be a non-empty object of permission name to { rules }");for(let r of Object.keys(t.permissions)){Es.test(r)||d(".permissions."+r,'is not a valid permission name (lower case words joined by ".", "_" or "-")');let o=t.permissions[r];$(o)||d(".permissions."+r,"must be an object { label?, rules }"),o.label!==void 0&&typeof o.label!="string"&&d(".permissions."+r+".label","must be a string"),(!Array.isArray(o.rules)||o.rules.length===0)&&d(".permissions."+r+".rules","must be a non-empty array"),o.rules.forEach((i,c)=>Rs(e,s,r,i,c))}$(t.gates)||d(".gates","is required: { roles, grants }, two declared permissions");for(let r of["roles","grants"]){let o=t.gates[r];_(t,o)||d(".gates."+r,JSON.stringify(o)+" is not a declared permission")}if(t.subjects!==void 0){$(t.subjects)||d(".subjects",'must be an object of subject name to "*" or a permission list');for(let r of Object.keys(t.subjects)){let o=e.subjects&&e.subjects[r];o||d(".subjects."+r,"is not declared in policy.subjects"),typeof o.role!="string"&&d(".subjects."+r,"must be a role: subject; only a Wix member role can count as a site-wide grant");let i=t.subjects[r];if(i!=="*"){Array.isArray(i)||d(".subjects."+r,'must be "*" or an array of permission names');for(let c of i)_(t,c)||d(".subjects."+r,JSON.stringify(c)+" is not a declared permission")}}}return t.store!==void 0&&Ss(e,t),t}var M={ANYONE:"anyone",ANONYMOUS:"anonymous",MEMBER:"member"},S=e=>!!e&&typeof e=="object"&&!Array.isArray(e),Fs=e=>Array.isArray(e)?e:[e];function y(e,t){throw new R("policy"+e+": "+t)}function _s(e,t){let s=".subjects."+e;S(t)||y(s,"must be an object");let r=["when","role","domain"].filter(o=>t[o]!==void 0);if(r.length===0&&y(s,'needs exactly one of when/role/domain \u2014 "{}" is ambiguous between a visitor and a member'),r.length>1&&y(s,"has "+r.join(" and ")+"; use exactly one"),t.when!==void 0){let o=[M.ANYONE,M.ANONYMOUS,M.MEMBER];o.indexOf(t.when)===-1&&y(s+".when","must be one of "+o.join(", ")+" (got "+JSON.stringify(t.when)+")")}t.role!==void 0&&typeof t.role!="string"&&y(s+".role","must be a string"),t.domain!==void 0&&typeof t.domain!="string"&&y(s+".domain","must be a string")}function Ms(e,t,s){let n=".rules["+t+"]";S(e)||y(n,"must be an object"),typeof e.subject!="string"&&y(n+".subject","must be a string"),s.indexOf(e.subject)===-1&&y(n+".subject",'"'+e.subject+'" is not declared in policy.subjects'),e.actions===void 0&&y(n+".actions","is required");for(let r of Fs(e.actions))typeof r!="string"&&y(n+".actions","must be a string or an array of strings");typeof e.resource!="string"&&y(n+".resource","must be a string"),e.where!==void 0&&!S(e.where)&&y(n+".where","must be an object")}var $t=["Anyone","SiteMember","Admin"];function Cs(e,t,s){let n=".api."+e;S(t)||y(n,"must be an object"),$t.indexOf(t.permission)===-1&&y(n+".permission","must be one of "+$t.join(", ")+" (got "+JSON.stringify(t.permission)+")"),t.ability!==void 0&&((!Array.isArray(t.ability)||t.ability.length!==2)&&y(n+".ability","must be [action, resource]"),(typeof t.ability[0]!="string"||typeof t.ability[1]!="string")&&y(n+".ability","both entries must be strings")),t.subject!==void 0&&s.indexOf(t.subject)===-1&&y(n+".subject",'"'+t.subject+'" is not declared in policy.subjects')}var Ds=["resource","owner","actor","tenant","profile"];function Ts(e,t){let s=".collections."+e;S(t)||y(s,"must be an object");for(let n of Ds)t[n]!==void 0&&(typeof t[n]!="string"||!t[n])&&y(s+"."+n,"must be a non-empty string");t.owner!==void 0&&t.owner===t.actor&&y(s,'owner and actor must be different fields (both are "'+t.owner+'")')}function Nt(e){if(!S(e))throw new R("policy must be an object");S(e.subjects)||y(".subjects","is required and must be an object");let t=Object.keys(e.subjects);t.length===0&&y(".subjects","declares no subjects");for(let s of t)_s(s,e.subjects[s]);if(Array.isArray(e.rules)||y(".rules","is required and must be an array"),e.rules.forEach((s,n)=>Ms(s,n,t)),e.api!==void 0){S(e.api)||y(".api","must be an object");for(let s of Object.keys(e.api))Cs(s,e.api[s],t)}if(e.collections!==void 0){S(e.collections)||y(".collections","must be an object");for(let s of Object.keys(e.collections))Ts(s,e.collections[s])}return e.catalogue!==void 0&&ie(e),e}function ae(e,t){let s=new Set(e.subjects||[]);for(let n of Object.keys(t.subjects)){let r=t.subjects[n];(r.when===M.ANYONE||r.when===M.ANONYMOUS&&!e.memberId||r.when===M.MEMBER&&e.memberId||r.role!==void 0&&e.roles.indexOf(r.role)!==-1||r.domain!==void 0&&e.domain[r.domain])&&s.add(n)}return Array.from(s)}function kt(e,t){let s=e.api&&e.api[t];return s?s.permission:null}var ce=class{constructor(t,s){this.operator=t,this.value=s,Object.defineProperty(this,"t",{writable:!0})}get notes(){return this.t}addNote(t){this.t=this.t||[],this.t.push(t)}},H=class extends ce{},P=class extends H{constructor(t,s){if(!Array.isArray(s))throw new Error(`"${t}" operator expects to receive an array of conditions`);super(t,s)}},C="__itself__",L=class extends ce{constructor(t,s,n){super(t,n),this.field=s}},Re=new H("__null__",null),ke=Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);function Ps(e,t){return t instanceof P&&t.operator===e}function Se(e,t){return t.length===1?t[0]:new P(e,(function s(n,r,o){let i=o||[];for(let c=0,u=r.length;c<u;c++){let a=r[c];Ps(n,a)?s(n,a.value,i):i.push(a)}return i})(e,t))}var Ls=e=>e,Rt=()=>Object.create(null),St=Object.defineProperty(Rt(),"__@type@__",{value:"ignore value"});function Gs(e,t,s=!1){if(!e||e&&e.constructor!==Object)return!1;for(let n in e)if(ke(e,n)&&ke(t,n)&&(!s||e[n]!==St))return!0;return!1}function Us(e){let t=[];for(let s in e)ke(e,s)&&e[s]!==St&&t.push(s);return t}function $e(e,t){t!==Re&&e.push(t)}var Fe=e=>Se("and",e);var ue={compound(e,t,s){let n=(Array.isArray(t)?t:[t]).map(r=>s.parse(r));return new P(e.name,n)},field:(e,t,s)=>new L(e.name,s.field,t),document:(e,t)=>new H(e.name,t)},Q=class{constructor(t,s=Rt()){this.o=void 0,this.s=void 0,this.i=void 0,this.u=void 0,this.h=void 0,this.parse=this.parse.bind(this),this.u={operatorToConditionName:s.operatorToConditionName||Ls,defaultOperatorName:s.defaultOperatorName||"eq",mergeFinalConditions:s.mergeFinalConditions||Fe},this.o=Object.keys(t).reduce((n,r)=>(n[r]=Object.assign({name:this.u.operatorToConditionName(r)},t[r]),n),{}),this.s=Object.assign({},s.fieldContext,{field:"",query:{},parse:this.parse,hasOperators:n=>Gs(n,this.o,s.useIgnoreValue)}),this.i=Object.assign({},s.documentContext,{parse:this.parse,query:{}}),this.h=s.useIgnoreValue?Us:Object.keys}setParse(t){this.parse=t,this.s.parse=t,this.i.parse=t}parseField(t,s,n,r){let o=this.o[s];if(!o)throw new Error(`Unsupported operator "${s}"`);if(o.type!=="field")throw new Error(`Unexpected ${o.type} operator "${s}" at field level`);return this.s.field=t,this.s.query=r,this.parseInstruction(o,n,this.s)}parseInstruction(t,s,n){return typeof t.validate=="function"&&t.validate(t,s),(t.parse||ue[t.type])(t,s,n)}parseFieldOperators(t,s){let n=[],r=this.h(s);for(let o=0,i=r.length;o<i;o++){let c=r[o];if(!this.o[c])throw new Error(`Field query for "${t}" may contain only operators or a plain object as a value`);$e(n,this.parseField(t,c,s[c],s))}return n}parse(t){let s=[],n=this.h(t);this.i.query=t;for(let r=0,o=n.length;r<o;r++){let i=n[r],c=t[i],u=this.o[i];if(u){if(u.type!=="document"&&u.type!=="compound")throw new Error(`Cannot use parsing instruction for operator "${i}" in "document" context as it is supposed to be used in "${u.type}" context`);$e(s,this.parseInstruction(u,c,this.i))}else this.s.hasOperators(c)?s.push(...this.parseFieldOperators(i,c)):$e(s,this.parseField(i,this.u.defaultOperatorName,c,t))}return this.u.mergeFinalConditions(s)}};function Ne(e,t){let s=e[t];if(typeof s!="function")throw new Error(`Unable to interpret "${t}" condition. Did you forget to register interpreter for it?`);return s}function Bs(e){return e.operator}function Ft(e,t){let s=t,n=s&&s.getInterpreterName||Bs,r;switch(s?s.numberOfArguments:0){case 1:r=i=>{let c=n(i,s);return Ne(e,c)(i,o)};break;case 3:r=(i,c,u)=>{let a=n(i,s);return Ne(e,a)(i,c,u,o)};break;default:r=(i,c)=>{let u=n(i,s);return Ne(e,u)(i,c,o)}}let o=Object.assign({},s,{interpret:r});return o.interpret}function _t(e,t){return(s,...n)=>{let r=e(s,...n),o=t.bind(null,r);return o.ast=r,o}}var Jn=Q.prototype.parseInstruction;function Mt(e,t){if(!Array.isArray(t))throw new Error(`"${e.name}" expects value to be an array`)}function Ct(e,t){if(Mt(e,t),!t.length)throw new Error(`"${e.name}" expects to have at least one element in array`)}var _e=e=>(t,s)=>{if(typeof s!==e)throw new Error(`"${t.name}" expects value to be a "${e}"`)},Dt={type:"compound",validate:Ct,parse(e,t,{parse:s}){let n=t.map(r=>s(r));return Se(e.name,n)}},qs=Dt,Vs={type:"compound",validate:Ct},zs={type:"field",validate(e,t){if(!(t&&(t instanceof RegExp||t.constructor===Object)))throw new Error(`"${e.name}" expects to receive either regular expression or object of field operators`)},parse(e,t,s){let n=t instanceof RegExp?new L("regex",s.field,t):s.parse(t,s);return new P(e.name,[n])}},Me={type:"field",validate(e,t){if(!t||t.constructor!==Object)throw new Error(`"${e.name}" expects to receive an object with nested query or field level operators`)},parse(e,t,{parse:s,field:n,hasOperators:r}){let o=r(t)?s(t,{field:C}):s(t);return new L(e.name,n,o)}},Ce={type:"field",validate:_e("number")},X={type:"field",validate:Mt},De=X,Te=X,Ks={type:"field",validate(e,t){if(!Array.isArray(t)||t.length!==2)throw new Error(`"${e.name}" expects an array with 2 numeric elements`)}},Pe={type:"field",validate:_e("boolean")},fe={type:"field",validate:function(e,t){if(!(typeof t=="string"||typeof t=="number"||t instanceof Date))throw new Error(`"${e.name}" expects value to be comparable (i.e., string, number or date)`)}},ee=fe,Le=ee,Ge=ee,de={type:"field"},Ue=de,Be={type:"field",validate(e,t){if(!(t instanceof RegExp)&&typeof t!="string")throw new Error(`"${e.name}" expects value to be a regular expression or a string that represents regular expression`)},parse(e,t,s){let n=typeof t=="string"?new RegExp(t,s.query.$options||""):t;return new L(e.name,s.field,n)}},qe={type:"field",parse:()=>Re},Js={type:"document",validate:_e("function")},Ws=Object.freeze({__proto__:null,$and:Dt,$or:qs,$nor:Vs,$not:zs,$elemMatch:Me,$size:Ce,$in:X,$nin:De,$all:Te,$mod:Ks,$exists:Pe,$gte:fe,$gt:ee,$lt:Le,$lte:Ge,$eq:de,$ne:Ue,$regex:Be,$options:qe,$where:Js}),le=class extends Q{constructor(t){super(t,{defaultOperatorName:"$eq",operatorToConditionName:s=>s.slice(1)})}parse(t,s){return s&&s.field?Fe(this.parseFieldOperators(s.field,t)):super.parse(t)}},pe=Ws;function Ve(e,t,s){for(let n=0,r=e.length;n<r;n++)if(s(e[n],t)===0)return!0;return!1}function ze(e,t){return Array.isArray(e)&&Number.isNaN(Number(t))}function Tt(e,t,s){if(!ze(e,t))return s(e,t);let n=[];for(let r=0;r<e.length;r++){let o=s(e[r],t);o!==void 0&&(n=n.concat(o))}return n}function G(e){return(t,s,n)=>{let r=n.get(s,t.field);return Array.isArray(r)?r.some(o=>e(t,o,n)):e(t,r,n)}}var Ys=Object.hasOwn||Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty),Zs=(e,t)=>e[t];function Pt(e,t,s){let n=t.lastIndexOf(".");return n===-1?[e,t]:[s(e,t.slice(0,n)),t.slice(n+1)]}function Hs(e,t,s=Zs){if(t===C)return e;if(!e)throw new Error(`Unable to get field "${t}" out of ${String(e)}.`);return(function(n,r,o){if(r.indexOf(".")===-1)return Tt(n,r,o);let i=r.split("."),c=n;for(let u=0,a=i.length;u<a;u++)if(c=Tt(c,i[u],o),!c||typeof c!="object")return u<a-1?void 0:c;return c})(e,t,s)}function Ke(e,t){return e===t?0:e>t?1:-1}function Je(e,t={}){return Ft(e,Object.assign({get:Hs,compare:Ke},t))}var Lt=(e,t,{interpret:s})=>e.value.some(n=>s(n,t)),Qs=(e,t,s)=>!Lt(e,t,s),We=(e,t,{interpret:s})=>e.value.every(n=>s(n,t)),Xs=(e,t,{interpret:s})=>!s(e.value[0],t),he=(e,t,{compare:s,get:n})=>{let r=n(t,e.field);return Array.isArray(r)&&!Array.isArray(e.value)?Ve(r,e.value,s):s(r,e.value)===0},Ye=(e,t,s)=>!he(e,t,s),Ze=G((e,t,s)=>{let n=s.compare(t,e.value);return n===0||n===-1}),He=G((e,t,s)=>s.compare(t,e.value)===-1),Qe=G((e,t,s)=>s.compare(t,e.value)===1),Xe=G((e,t,s)=>{let n=s.compare(t,e.value);return n===0||n===1}),et=(e,t,{get:s})=>{if(e.field===C)return t!==void 0;let[n,r]=Pt(t,e.field,s),o=i=>i==null?!!i===e.value:Ys(i,r)===e.value;return ze(n,r)?n.some(o):o(n)},en=G((e,t)=>typeof t=="number"&&t%e.value[0]===e.value[1]),tt=(e,t,{get:s})=>{let[n,r]=Pt(t,e.field,s),o=i=>{let c=s(i,r);return Array.isArray(c)&&c.length===e.value};return e.field!==C&&ze(n,r)?n.some(o):o(n)},st=G((e,t)=>typeof t=="string"&&e.value.test(t)),te=G((e,t,{compare:s})=>Ve(e.value,t,s)),nt=(e,t,s)=>!te(e,t,s),rt=(e,t,{compare:s,get:n})=>{let r=n(t,e.field);return Array.isArray(r)&&e.value.every(o=>Ve(r,o,s))},ot=(e,t,{interpret:s,get:n})=>{let r=n(t,e.field);return Array.isArray(r)&&r.some(o=>s(e.value,o))},tn=(e,t)=>e.value.call(t),sn=Object.freeze({__proto__:null,or:Lt,nor:Qs,and:We,not:Xs,eq:he,ne:Ye,lte:Ze,lt:He,gt:Qe,gte:Xe,exists:et,mod:en,size:tt,regex:st,within:te,nin:nt,all:rt,elemMatch:ot,where:tn}),me=Object.assign({},sn,{in:te}),Xn=Je(me);function Gt(e){return e===null||typeof e!="object"?e:e instanceof Date?e.getTime():e&&typeof e.toJSON=="function"?e.toJSON():e}var nn=(e,t)=>Ke(Gt(e),Gt(t));function ye(e,t,s){let n=new le(e),r=Je(t,Object.assign({compare:nn},s));if(s&&s.forPrimitives){let o={field:C},i=n.parse;n.setParse(c=>i(c,o))}return _t(n.parse,r)}var rr=ye(pe,me),or=ye(["$and","$or"].reduce((e,t)=>(e[t]=Object.assign({},e[t],{type:"field"}),e),Object.assign({},pe,{$nor:Object.assign({},pe.$nor,{type:"field",parse:ue.compound})})),me,{forPrimitives:!0});var Kt=Object.hasOwn||((e,t)=>Object.prototype.hasOwnProperty.call(e,t));function it(e){return Array.isArray(e)?e:[e]}var z="__caslSubjectType__";function Jt(e,t){if(t){if(!Kt(t,z))Object.defineProperty(t,z,{value:e});else if(e!==t[z])throw new Error(`Trying to cast object to subject type ${e} but previously it was casted to ${t[z]}`)}return t}var ge=e=>{let t=typeof e;return t==="string"||t==="function"},Wt=e=>e.modelName||e.name;function rn(e){return typeof e=="string"?e:Wt(e)}function Yt(e){return Kt(e,z)?e[z]:Wt(e.constructor)}var Ut={function:e=>e.constructor,string:Yt};function Bt(e,t,s){for(let n=s;n<t.length;n++)e.push(t[n])}function qt(e,t){if(!e||!e.length)return t||[];if(!t||!t.length)return e||[];let s=0,n=0,r=[];for(;s<e.length&&n<t.length;)e[s].priority<t[n].priority?(r.push(e[s]),s++):e[s].priority>t[n].priority?(r.push(t[n]),n++):(r.push(e[s]),s++,n++);return Bt(r,e,s),Bt(r,t,n),r}function be(e,t,s){let n=e.get(t);return n||(n=s(),e.set(t,n)),n}var on=e=>e;function an(e,t){let s;for(let n=0;n<e.length;n++){let r=t(e[n]);s&&r&&s.push(e[n]),r||(s??(s=e.slice(0,n)))}return s||e}function cn(e,t){if(Array.isArray(e.fields)&&!e.fields.length)throw new Error("`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa");if(e.fields&&!t.fieldMatcher)throw new Error('You need to pass "fieldMatcher" option in order to restrict access by fields');if(e.conditions&&!t.conditionsMatcher)throw new Error('You need to pass "conditionsMatcher" option in order to restrict access by conditions')}var at=class{constructor(t,s,n=0){cn(t,s),this.action=s.resolveAction(t.action),this.subject=t.subject,this.inverted=!!t.inverted,this.conditions=t.conditions,this.reason=t.reason,this.origin=t,this.fields=t.fields?it(t.fields):void 0,this.priority=n,this.t=s}i(){return this.conditions&&!this.o&&(this.o=this.t.conditionsMatcher(this.conditions)),this.o}get ast(){let t=this.i();return t?t.ast:void 0}matchesConditions(t){return this.conditions?!t||ge(t)?!this.inverted:this.i()(t):!0}matchesField(t){return this.fields?t?(this.u||(this.u=this.t.fieldMatcher(this.fields)),this.u(t)):!this.inverted:!0}};function un(e,t){let s={value:e,prev:t,next:null};return t&&(t.next=s),s}function ln(e){e.next&&(e.next.prev=e.prev),e.prev&&(e.prev.next=e.next),e.next=e.prev=null}var Vt=()=>({rules:[],merged:!1}),zt=()=>new Map,ct=class{constructor(t=[],s={}){this.h=!1,this.l=new Map,this.p={conditionsMatcher:s.conditionsMatcher,fieldMatcher:s.fieldMatcher,resolveAction:s.resolveAction||on},this.$=s.anyAction||"manage",this.A=s.anySubjectType||"all",this.m=t,this.M=!!s.detectSubjectType,this.j=s.detectSubjectType||Yt,this.v(t)}get rules(){return this.m}detectSubjectType(t){return ge(t)?t:t?this.j(t):this.A}update(t){let s={rules:t,ability:this,target:this};return this._("update",s),this.m=t,this.v(t),this._("updated",s),this}v(t){let s=new Map,n;for(let r=t.length-1;r>=0;r--){let o=t.length-r-1,i=new at(t[r],this.p,o),c=it(i.action),u=it(i.subject||this.A);!this.h&&i.fields&&(this.h=!0);for(let a=0;a<u.length;a++){let f=be(s,u[a],zt);n===void 0&&(n=typeof u[a]),typeof u[a]!==n&&n!=="mixed"&&(n="mixed");for(let p=0;p<c.length;p++)be(f,c[p],Vt).rules.push(i)}}if(this.l=s,n!=="mixed"&&!this.M){let r=Ut[n]||Ut.string;this.j=r}}possibleRulesFor(t,s=this.A){if(!ge(s))throw new Error('"possibleRulesFor" accepts only subject types (i.e., string or class) as the 2nd parameter');let n=be(this.l,s,zt),r=be(n,t,Vt);if(r.merged)return r.rules;let o=t!==this.$&&n.has(this.$)?n.get(this.$).rules:void 0,i=qt(r.rules,o);return s!==this.A&&(i=qt(i,this.possibleRulesFor(t,this.A))),r.rules=i,r.merged=!0,i}rulesFor(t,s,n){let r=this.possibleRulesFor(t,s);if(n&&typeof n!="string")throw new Error("The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details");return this.h?an(r,o=>o.matchesField(n)):r}actionsFor(t){if(!ge(t))throw new Error('"actionsFor" accepts only subject types (i.e., string or class) as a parameter');let s=new Set,n=this.l.get(t);n&&Array.from(n.keys()).forEach(o=>s.add(o));let r=t!==this.A?this.l.get(this.A):void 0;return r&&Array.from(r.keys()).forEach(o=>s.add(o)),Array.from(s)}on(t,s){this.F=this.F||new Map;let n=this.F,r=n.get(t)||null,o=un(s,r);return n.set(t,o),()=>{let i=n.get(t);!o.next&&!o.prev&&i===o?n.delete(t):o===i&&n.set(t,o.prev),ln(o)}}_(t,s){if(!this.F)return;let n=this.F.get(t)||null,r=[];for(;n!==null;)r.push(n.value),n=n.prev;for(let o=0;o<r.length;o++)r[o](s)}},ut=class extends ct{can(t,s,n){let r=this.relevantRuleFor(t,s,n);return!!r&&!r.inverted}relevantRuleFor(t,s,n){let r=this.detectSubjectType(s),o=this.rulesFor(t,r,n);for(let i=0,c=o.length;i<c;i++)if(o[i].matchesConditions(s))return o[i];return null}cannot(t,s,n){return!this.can(t,s,n)}},fn={$eq:de,$ne:Ue,$lt:Le,$lte:Ge,$gt:ee,$gte:fe,$in:X,$nin:De,$all:Te,$size:Ce,$regex:Be,$options:qe,$elemMatch:Me,$exists:Pe},dn={eq:he,ne:Ye,lt:He,lte:Ze,gt:Qe,gte:Xe,in:te,nin:nt,all:rt,size:tt,regex:st,elemMatch:ot,exists:et,and:We};var pn=ye(fn,dn),hn=/[-/\\^$+?.()|[\]{}]/g,mn=/\.?\*+\.?/g,yn=/\*+/,bn=/\./g;function gn(e,t,s){let n=s[0]==="*"||e[0]==="."&&e[e.length-1]==="."?"+":"*",r=e.indexOf("**")===-1?"[^.]":".",o=e.replace(bn,"\\$&").replace(yn,r+n);return t+e.length===s.length?`(?:${o})?`:o}function On(e,t,s){return e==="."&&(s[t-1]==="*"||s[t+1]==="*")?e:`\\${e}`}function An(e){let t=e.map(n=>n.replace(hn,On).replace(mn,gn)),s=t.length>1?`(?:${t.join("|")})`:t[0];return new RegExp(`^${s}$`)}var jn=e=>{let t;return s=>(typeof t>"u"&&(t=e.every(n=>n.indexOf("*")===-1)?null:An(e)),t===null?e.indexOf(s)!==-1:t.test(s))};function Zt(e=[],t={}){return new ut(e,Object.assign({conditionsMatcher:pn,fieldMatcher:jn},t))}var wn=e=>`Cannot execute "${e.action}" on "${e.subjectType}"`,Ht=function(t){this.message=t};Ht.prototype=Object.create(Error.prototype);var lt=class extends Ht{static setDefaultMessage(t){this.P=typeof t=="string"?()=>t:t}static from(t){return new this(t)}constructor(t){super(""),this.ability=t,typeof Error.captureStackTrace=="function"&&(this.name="ForbiddenError",Error.captureStackTrace(this,this.constructor))}setMessage(t){return this.message=t,this}throwUnlessCan(t,s,n){let r=this.unlessCan(t,s,n);if(r)throw r}unlessCan(t,s,n){let r=this.ability.relevantRuleFor(t,s,n);if(r&&!r.inverted)return;this.action=t,this.subject=s,this.subjectType=rn(this.ability.detectSubjectType(s)),this.field=n;let o=r?r.reason:"";return this.message=this.message||o||this.constructor.P(this),this}};lt.P=wn;var fr=Object.freeze({__proto__:null});function ft(e,t,s){if(e==null)return e;if(typeof e=="string"){if(e.indexOf("$principal.")!==0)return e;let r=e.slice(11).split(".").reduce((o,i)=>o==null?o:o[i],t);return r==null&&(s.unresolved=!0),r}if(Array.isArray(e))return e.map(n=>ft(n,t,s));if(typeof e=="object"){let n={};for(let r of Object.keys(e))n[r]=ft(e[r],t,s);return n}return e}function U(e,t){let s={unresolved:!1};return{conditions:ft(e,t,s),unresolved:s.unresolved}}function dt(e,t){return U(e,t).conditions}var E=e=>!!e&&typeof e=="object"&&!Array.isArray(e),k=e=>typeof e=="string"&&e.length>0,Oe=e=>e.owner===null||e.owner===void 0;function K(e,t){e.indexOf(t)===-1&&e.push(t)}function xn(e,t){let s=t&&t.catalogue;if(!s||!E(s.subjects)||!e)return[];let n=Array.isArray(e.roles)?e.roles:[],r=[];for(let o of Object.keys(s.subjects)){let i=t.subjects&&t.subjects[o];if(!i||typeof i.role!="string"||n.indexOf(i.role)===-1)continue;let c=s.subjects[o],u=c==="*"?Object.keys(s.permissions):(Array.isArray(c)?c:[]).filter(a=>_(s,a));r.push({subject:o,permissions:u})}return r}function vn(e,t,s,n){let r={},o=n.indexOf(t);for(let i=0;i<=o;i++){let c=n[i];k(e[c])&&(r[c]=e[c])}return r[t]=s,r}function En(e,t,s,n){let r={};for(let o of n){let i=[];for(let c of Array.isArray(e[o])?e[o]:[])k(c)&&K(i,c);o===t&&K(i,s),i.length&&(r[o]=i)}return r}function es(e,t,s){let n={grants:[],ignored:[]},r=e&&e.catalogue;if(!E(r)||!E(s))return n;let o=r.scopes,i=Array.isArray(s.roles)?s.roles:[],c=Array.isArray(s.grants)?s.grants:[],u=t&&k(t.memberId)?t.memberId:null;for(let a of c){let f=(v,bs)=>{let gs={reason:v,grant:E(a)&&a._id!==void 0?a._id:null,role:E(a)&&a.role!==void 0?a.role:null};n.ignored.push(Object.assign(gs,bs||{}))};if(!E(a)){f("malformed");continue}if(!u||a.memberId!==u){f("notCaller");continue}if(a.isArchived===!0){f("archived");continue}if(a.status!==void 0&&a.status!==null&&a.status!==""&&a.status!=="ACTIVE"){f("inactive");continue}let p=a.scopeKind,h=p===x;if(!(h?a.scopeId===null||a.scopeId===void 0:o.indexOf(p)!==-1&&k(a.scopeId))){f("unknownScope");continue}let O=E(a.path)?a.path:{};if(!h&&O[p]!==void 0&&O[p]!==a.scopeId){f("badPath");continue}let l=null;if(k(a.role)){for(let v of i)if(E(v)&&v._id===a.role){l=v;break}}if(!l){f("roleNotFound");continue}if(l.isArchived===!0){f("roleArchived");continue}let m=h?{}:vn(O,p,a.scopeId,o),j=Oe(l)?null:l.owner;if(j!==null&&!(k(j)&&k(r.roleOwner)&&!h&&k(m[r.roleOwner])&&m[r.roleOwner]===j)){f("outsideOwner");continue}let N=[],V=[];for(let v of Array.isArray(l.permissions)?l.permissions:[])_(r,v)?K(N,v):V.indexOf(v)===-1&&(V.push(v),f("unknownPermission",{permission:v}));n.grants.push({id:a._id!==void 0?a._id:null,role:l._id,roleOwner:j,scope:{kind:p,id:h?null:a.scopeId},path:m,covers:h?{}:En(E(a.covers)?a.covers:{},p,a.scopeId,o),permissions:N})}return n}function pt(e,t){let s=[];for(let n of e&&Array.isArray(e.grants)?e.grants:[])!E(n)||!E(n.scope)||!Array.isArray(n.permissions)||s.push({scope:{kind:n.scope.kind,id:n.scope.kind===x?null:n.scope.id},permissions:n.permissions,covers:E(n.covers)?n.covers:{},path:E(n.path)?n.path:{}});for(let n of xn(e,t))s.push({scope:{kind:x,id:null},permissions:n.permissions,covers:{},path:{},subject:n.subject});return s}function Qt(e,t){let s=E(t),n=s?t.kind:t,r=[];for(let o of Array.isArray(e.covers[n])?e.covers[n]:[])k(o)&&K(r,o);return s&&k(e.path[n])&&K(r,e.path[n]),r}function In(e,t){let s=t.catalogue,n=pt(e,t);if(n.length===0)return[];let r=[],o={},i=c=>{let u=JSON.stringify(c);o[u]||(o[u]=!0,r.push(c))};for(let c of Object.keys(s.permissions)){let u=n.filter(a=>a.permissions.indexOf(c)!==-1);if(u.length!==0)for(let a of s.permissions[c].rules){let f=null;if(a.where){let g=U(a.where,e);if(g.unresolved)continue;f=g.conditions}let p=Array.isArray(a.actions)?a.actions.slice():a.actions;if(a.scope==="any"||u.some(g=>g.scope.kind===x)){let g={action:p,subject:a.resource};f&&(g.conditions=f),i(g);continue}let h=Object.keys(a.scope);if(h.length===1){let g=h[0],O=[];for(let l of u)for(let m of Qt(l,a.scope[g]))K(O,m);if(O.length===0)continue;i({action:p,subject:a.resource,conditions:Object.assign({},f||{},{[g]:{$in:O}})});continue}for(let g of u){let O=Object.assign({},f||{}),l=!0;for(let m of h){let j=Qt(g,a.scope[m]);if(j.length===0){l=!1;break}O[m]={$in:j}}l&&i({action:p,subject:a.resource,conditions:O})}}}return r}var Xt="__wixAccessGrantRules";function Ae(e,t){if(!t||!E(t.catalogue)||!e||typeof e!="object")return[];let s=e[Xt];if(s&&s.policy===t&&s.grants===e.grants&&s.roles===e.roles&&s.domain===e.domain&&s.subjects===e.subjects&&s.memberId===e.memberId)return s.rules.slice();let n=In(e,t);try{Object.defineProperty(e,Xt,{value:{policy:t,grants:e.grants,roles:e.roles,domain:e.domain,subjects:e.subjects,memberId:e.memberId,rules:n},enumerable:!1,configurable:!0,writable:!0})}catch{}return n.slice()}function se(e,t){let s=ae(e,t),n=[];for(let r of t.rules){if(s.indexOf(r.subject)===-1)continue;let o={action:r.actions,subject:r.resource};if(r.where){let{conditions:i,unresolved:c}=U(r.where,e);if(c)continue;o.conditions=i}n.push(o)}if(t.catalogue)for(let r of Ae(e,t))n.push(r);return n}function J(e){return Zt(Array.isArray(e)?e:[])}function ts(e,t){return J(se(e,t))}function B(e,t,s,n){return n==null?e.can(t,s):e.can(t,Jt(s,Object.assign({},n)))}var F={ALL:"all",NONE:"none",FIELDS:"fields",AMBIGUOUS:"ambiguous"},ss={$in:"in",$nin:"nin",$ne:"ne",$gt:"gt",$gte:"gte",$lt:"lt",$lte:"lte"};function $n(e){let t=[];for(let s of Object.keys(e)){let n=e[s];if(n===null||typeof n!="object"||Array.isArray(n)){t.push({field:s,op:"eq",value:n});continue}let r=Object.keys(n);if(r.length!==1||!ss[r[0]])return null;t.push({field:s,op:ss[r[0]],value:n[r[0]]})}return t}var Nn=(e,t)=>e==="manage"||e===t||Array.isArray(e)&&(e.indexOf(t)!==-1||e.indexOf("manage")!==-1),kn=(e,t)=>e==="all"||e===t,ns=e=>typeof e=="string"||typeof e=="number"&&Number.isFinite(e);function Rn(e){let t=null,s=[];for(let n of e){let r=Object.keys(n.conditions);if(r.length!==1)return null;if(t===null)t=r[0];else if(r[0]!==t)return null;let o=n.conditions[t];if(ns(o)){s.indexOf(o)===-1&&s.push(o);continue}if(!o||typeof o!="object"||Array.isArray(o))return null;let i=Object.keys(o);if(i.length!==1||i[0]!=="$in"||!Array.isArray(o.$in)||!o.$in.every(ns))return null;for(let c of o.$in)s.indexOf(c)===-1&&s.push(c)}return{field:t,values:s}}function rs(e,t,s,n){let r=se(e,t).filter(i=>Nn(i.action,s)&&kn(i.subject,n));if(r.length===0)return{scope:F.NONE,clauses:[]};if(r.some(i=>!i.conditions))return{scope:F.ALL,clauses:[]};if(r.length>1){let i=Rn(r);return i?i.values.length===0?{scope:F.NONE,clauses:[]}:{scope:F.FIELDS,clauses:[{field:i.field,op:"in",value:i.values}]}:{scope:F.AMBIGUOUS,clauses:[]}}let o=$n(r[0].conditions);return o?{scope:F.FIELDS,clauses:o}:{scope:F.AMBIGUOUS,clauses:[]}}function os(e,t){let s=e;for(let n of t)n.op==="in"?s=s.hasSome(n.field,n.value):n.op==="nin"?s=s.not(s.hasSome(n.field,n.value)):s=s[n.op](n.field,n.value);return s}var ht=/export\s+const\s+([A-Za-z0-9_$]+)\s*=\s*webMethod\s*\(\s*Permissions\s*\.\s*([A-Za-z0-9_$]+)/g,Sn=[[/export\s*{\s*[A-Za-z0-9_$,\s]+}/,"export { x } \u2014 the call and the export must be one statement"],[/export\s+const\s+[A-Za-z0-9_$]+\s*=\s*webMethod\s*\(\s*Permissions\s*\[/,"Permissions['X'] \u2014 the property must be dotted and literal"],[/export\s+const\s+[A-Za-z0-9_$]+\s*=\s*webMethod\s*\(\s*[A-Za-z0-9_$]+\s*\(/,"a computed permission \u2014 it must be written out as Permissions.LEVEL"]];function mt(e){let t={},s=String(e||"");ht.lastIndex=0;let n=ht.exec(s);for(;n;)t[n[1]]=n[2],n=ht.exec(s);return t}function yt(e,t,s){let n=s||{},r=t&&t.api||{},o=mt(e),i=String(e||""),c=[],u=[];for(let h of Object.keys(o)){let g=r[h];g?g.permission!==o[h]&&c.push({name:h,declared:g.permission,written:o[h]}):u.push({name:h,gate:o[h]})}let a=n.complete?Object.keys(r).filter(h=>!(h in o)):[],f=[];for(let[h,g]of Sn)h.test(i)&&f.push(g);return{ok:c.length+u.length+a.length+f.length===0,found:o,mismatched:c,undeclared:u,missing:a,suspect:f}}function is(e,t,s){let n=yt(e,t,s);if(n.ok)return!0;let r=[];for(let o of n.mismatched)r.push(o.name+": policy says "+o.declared+", the export says "+o.written);for(let o of n.undeclared)r.push(o.name+": gated "+o.gate+" but missing from policy.api");for(let o of n.missing)r.push(o+": declared in policy.api but not exported here");for(let o of n.suspect)r.push("unreachable export shape \u2014 "+o);throw new Error(`wix-access: web-method gates do not match the policy:
|
|
2
2
|
`+r.join(`
|
|
3
|
-
`))}function
|
|
3
|
+
`))}function as(e,t){let s=t&&t.api||{},n=e||{},r={},o=[];for(let i of Object.keys(n)){let c=n[i],u=s[i];if(!u){o.push(i);continue}if(typeof c!="function"){o.push(i+" (not a function: "+typeof c+")");continue}try{c.permission=u.permission,r[i]=u.permission}catch(a){o.push(i+" (could not stamp: "+String(a&&a.message)+")")}}if(o.length)throw new Error("wix-access: applyGates could not gate: "+o.join(", ")+". Every exported web method must be declared in policy.api.");return r}var w=e=>!!e&&typeof e=="object"&&!Array.isArray(e),I=e=>typeof e=="string"&&e.length>0,W="defineRole",D="grantRole",bt={kind:x,id:null,path:{}};function us(e,t){return!t||!w(t.catalogue)||!e?[]:pt(e,t).map(s=>{let n={scope:{kind:s.scope.kind,id:s.scope.id},permissions:s.permissions.slice()};return s.subject&&(n.source="subject",n.subject=s.subject),n})}function gt(e,t){return w(e)?e.kind===x?!0:!I(e.kind)||!I(e.id)||!w(t)||!w(t.path)?!1:t.path[e.kind]===e.id:!1}function T(e,t,s){return Array.isArray(e)?e.some(n=>w(n)&&Array.isArray(n.permissions)&&n.permissions.indexOf(t)!==-1&>(n.scope,s)):!1}var je=e=>e&&w(e.catalogue)?e.catalogue:null;function ls(e,t){let s=[];for(let n of Array.isArray(e.permissions)?e.permissions:[])_(t,n)&&s.indexOf(n)===-1&&s.push(n);return s}function Fn(e,t){if(Oe(e))return bt;let s=I(t.roleOwner)?t.roleOwner:"owner";return I(e.owner)&&I(t.roleOwner)?{kind:s,id:e.owner,path:{[s]:e.owner}}:{kind:s,id:e.owner,path:{}}}function fs(){let e=[],t=[];return{list:e,add(s,n,r){let o=n+"|"+(r&&r.value!==void 0?JSON.stringify(r.value):s);t.indexOf(o)===-1&&(t.push(o),e.push(Object.assign({path:s,code:n},r||{})))}}}function Ot(e,t){if(!w(e))return[{path:"",code:"notAnObject"}];let s=je(t)||{},n=fs();return I(e.name)||n.add("name","missing"),Array.isArray(e.permissions)?e.permissions.forEach((r,o)=>{_(s,r)||n.add("permissions["+o+"]","unknownPermission",{value:r})}):n.add("permissions","notAnArray"),e.owner===void 0?n.add("owner","ownerMissing"):e.owner!==null&&(I(s.roleOwner)?I(e.owner)||n.add("owner","notAString"):n.add("owner","noRoleOwner")),e.isArchived!==void 0&&typeof e.isArchived!="boolean"&&n.add("isArchived","notABoolean"),n.list}function At(e,t,s){if(!w(e))return[{path:"",code:"notAnObject"}];let n=je(t)||{},r=Array.isArray(n.scopes)?n.scopes:[],o=fs(),i=I(e.memberId),c=I(e.email);if(e.memberId!==void 0&&e.memberId!==null&&!i&&o.add("memberId","notAString"),e.email!==void 0&&e.email!==null&&!c&&o.add("email","notAString"),!i&&!c&&o.add("memberId","missing"),!I(e.role))o.add("role","missing");else if(Array.isArray(s)){let u=s.filter(a=>w(a)&&a._id===e.role)[0];u?u.isArchived===!0&&o.add("role","roleArchived"):o.add("role","roleNotFound")}return e.scopeKind===x?e.scopeId!==null&&e.scopeId!==void 0&&o.add("scopeId","notNull"):r.indexOf(e.scopeKind)!==-1?I(e.scopeId)||o.add("scopeId","missing"):o.add("scopeKind","unknownScope"),e.isArchived!==void 0&&typeof e.isArchived!="boolean"&&o.add("isArchived","notABoolean"),e.status!==void 0&&e.status!==null&&typeof e.status!="string"&&o.add("status","notAString"),o.list}function we(e,t,s){let n=je(t);if(!n)return A(b.INVALID_ARGUMENT,W,{reason:"noCatalogue"});let r=s&&w(s.before)?s.before:null,o=s&&w(s.after)?s.after:null;if(!r&&!o)return A(b.INVALID_ARGUMENT,W,{reason:"nothingToCheck"});if(o){let c=Ot(o,t),u=c.filter(a=>a.code==="unknownPermission").map(a=>a.value);if(u.length)return A(b.INVALID_ARGUMENT,W,{reason:"unknownPermission",permissions:u});if(c.length)return A(b.INVALID_ARGUMENT,W,{reason:"invalidRow",problems:c})}let i=[["before",r],["after",o]];for(let[c,u]of i){if(!u)continue;let a=Fn(u,n);if(!T(e,n.gates.roles,a))return A(b.FORBIDDEN,W,{reason:"noGate",side:c});let f=ls(u,n).filter(p=>!T(e,p,a));if(f.length)return A(b.FORBIDDEN,W,{reason:"escalation",side:c,missing:f})}return Y(null)}function cs(e,t){return!w(e)||!w(t)?!1:t.scopeKind===x?e.kind===x:e.kind===t.scopeKind&&e.id===t.scopeId&&w(e.path)&&I(t.scopeId)&&e.path[t.scopeKind]===t.scopeId}function xe(e,t,s){let n=je(t);if(!n)return A(b.INVALID_ARGUMENT,D,{reason:"noCatalogue"});let r=w(s)?s:{},o=w(r.before)?r.before:null,i=w(r.after)?r.after:null;if(!o&&!i)return A(b.INVALID_ARGUMENT,D,{reason:"nothingToCheck"});let c=[];if(o){let u=null;o.scopeKind===x?u=bt:cs(r.beforeScope,o)&&(u=r.beforeScope),c.push({side:"before",role:w(r.beforeRole)?r.beforeRole:null,place:u})}if(i){let u=At(i,t);if(u.length)return A(b.INVALID_ARGUMENT,D,{reason:"invalidRow",problems:u});let a=r.role;if(!w(a)||a._id!==i.role||a.isArchived===!0)return A(b.INVALID_ARGUMENT,D,{reason:"roleNotFound"});let f=i.scopeKind===x&&(r.scope===void 0||r.scope===null)?bt:r.scope;if(!cs(f,i))return A(b.INVALID_ARGUMENT,D,{reason:"unknownScope"});c.push({side:"after",role:a,place:f})}for(let{side:u,role:a,place:f}of c){if(!T(e,n.gates.grants,f))return A(b.FORBIDDEN,D,{reason:"noGate",side:u});if(!a)continue;if(u==="after"&&!Oe(a)&&!(I(a.owner)&&I(n.roleOwner)&&w(f.path)&&f.path[n.roleOwner]===a.owner))return A(b.FORBIDDEN,D,{reason:"outsideOwner",side:u});let p=ls(a,n).filter(h=>!T(e,h,f));if(p.length)return A(b.FORBIDDEN,D,{reason:"escalation",side:u,missing:p})}return Y(null)}var jt="0.6.0";var wt=[{action:"read",type:"Booking",object:{customerId:"m-1"}},{action:"read",type:"Booking",object:{customerId:"m-2"}},{action:"cancel",type:"Booking",object:{customerId:"m-1"}},{action:"delete",type:"Booking",object:{customerId:"m-1"}},{action:"manage",type:"Vendor",object:{_id:"v-1"}}];function ds(e){return wt.map(t=>({action:t.action,type:t.type,object:t.object,can:B(e,t.action,t.type,t.object)}))}var ne=J([]),q=e=>!!e&&typeof e=="object"&&!Array.isArray(e),ps="no grants fetched";function _n(e){let t={};for(let s of Array.isArray(e.permissions)?e.permissions:[])t[s]={rules:[]};return{catalogue:{scopes:Array.isArray(e.scopes)?e.scopes:[],roleOwner:e.roleOwner||void 0,gates:q(e.gates)?e.gates:{},permissions:t}}}var hs="wix-access: createAccess({ fetchRules }) needs your web method, e.g. import { getMyAbilities } from 'backend/access.web'. The package cannot import it for you \u2014 that specifier only resolves inside your project. If it is imported and still not a function, build the kit inside onReady and pass an arrow: fetchRules: (...a) => getMyAbilities(...a).";function ms(e){let t=e||{},s=t.fetchRules,n=t.onError||null,r=typeof s!="function",o=ne,i=[],c=null,u=null,a=!1,f=!1,p=null,h=null;async function g(){if(c=null,u=null,r)return i=[],o=ne,f=!0,p=hs,a=!0,n&&n(new Error(hs)),O;try{let l=await s();if(re(l))return i=[],o=ne,f=!0,p="rules refused: "+(l.code||"FORBIDDEN"),a=!0,n&&n(new Error(p)),O;if(q(l)&&Object.prototype.hasOwnProperty.call(l,"rules")){if(!Array.isArray(l.rules))return i=[],o=ne,f=!0,p="the access answer carries no rules array",a=!0,n&&n(new Error(p)),O;i=l.rules,q(l.grants)&&(c=l.grants,u=_n(c))}else i=Array.isArray(l)?l:[];o=J(i),f=!1}catch(l){i=[],o=ne,f=!0,p=String(l&&l.message||l),n&&n(l)}return a=!0,O}let O={ready(){return a?Promise.resolve(O):(h||(h=g().then(l=>(h=null,l))),h)},refresh(){return a=!1,f=!1,p=null,h=null,O.ready()},can:(l,m,j)=>B(o,l,m,j),held:()=>c&&Array.isArray(c.held)?JSON.parse(JSON.stringify(c.held)):[],holds(l,m){return!c||!Array.isArray(c.held)?!1:m==null?c.held.some(j=>q(j)&&Array.isArray(j.permissions)&&j.permissions.indexOf(l)!==-1):T(c.held,l,m)},mayDefineRole(l,m){return c?we(c.held,u,{before:l||null,after:m||null}):A(b.FORBIDDEN,"defineRole",{reason:ps})},mayGrant(l){if(!c)return A(b.FORBIDDEN,"grantRole",{reason:ps});let m=q(l)?l:{};for(let j of["scope","beforeScope"]){let N=m[j];if(q(N)&&N.kind!==x&&!q(N.path))return A(b.FORBIDDEN,"grantRole",{reason:"noPath"})}return xe(c.held,u,m)},cannot:(l,m,j)=>!B(o,l,m,j),rules:()=>i.slice(),get loaded(){return a},get failed(){return f},get reason(){return p},guard(l,m,j,N,V){let v=O.can(m,j,N);return O.apply(l,v,V),v},apply(l,m,j){if(!l)return m;let N=j||"hide";try{N==="disable"?m&&l.enable?l.enable():!m&&l.disable&&l.disable():N==="collapse"?m&&l.expand?l.expand():!m&&l.collapse&&l.collapse():m&&l.show?l.show():!m&&l.hide&&l.hide()}catch(V){n&&n(V)}return m}};return O}function Mn(){return{ok:!0,side:"public",version:jt}}async function Cn(){try{return(await ys.currentMember.getRoles()).map(t=>t.title)}catch{return[]}}0&&(module.exports={CASES,CODES,KIND,PACKAGE_VERSION,PolicyError,SCOPE,SITE,WHEN,abilityFor,abilityFromRules,anonymous,applyClauses,applyGates,assertGates,can,caseTable,checkGrantRow,checkGrantWrite,checkRoleRow,checkRoleWrite,contains,createAccess,createPrincipal,deny,denyOpaque,filterFor,frontendRoleTitles,grantRulesFor,hasRole,heldBy,holdsAt,isDenial,normaliseRoles,ok,parseGates,permissionFor,publicPing,resolveGrants,resolvePlaceholders,resolveSubjects,resolveWhere,rulesFor,validateCatalogue,validatePolicy,verifyGates});
|
package/types.d.ts
CHANGED
|
@@ -45,6 +45,157 @@ export interface Policy {
|
|
|
45
45
|
rules: Rule[]
|
|
46
46
|
collections?: Record<string, CollectionSpec>
|
|
47
47
|
api?: Record<string, ApiEntry>
|
|
48
|
+
/** 0.6.0: roles and grants as data. Absent, the policy behaves exactly as 0.5.x. */
|
|
49
|
+
catalogue?: Catalogue
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ---------------------------------------------------------------- catalogue (0.6.0)
|
|
53
|
+
/** A scope kind from `catalogue.scopes`, or `'site'` (implicit, contains everything). */
|
|
54
|
+
export type ScopeKind = string
|
|
55
|
+
|
|
56
|
+
/** A place: `path` holds the ids it sits under, itself included (`{}` for the site). */
|
|
57
|
+
export interface ScopeRef {
|
|
58
|
+
kind: ScopeKind
|
|
59
|
+
id: string | null
|
|
60
|
+
path?: Record<string, string>
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Which grants reach a row: `'any'` (any holder, anywhere — read rules only), or a map of
|
|
65
|
+
* row field to scope kind. A plain kind reads the grant's `covers[kind]`; `{ kind, upward:
|
|
66
|
+
* true }` also admits the grant's own ancestor `path[kind]`, and needs a plain field beside it.
|
|
67
|
+
* A rule with any action but `read` must pin its collection's `tenant` field.
|
|
68
|
+
*/
|
|
69
|
+
export type CatalogueScope = 'any' | Record<string, string | { kind: string; upward: true }>
|
|
70
|
+
|
|
71
|
+
export interface CatalogueRule {
|
|
72
|
+
/** Never `manage`. */
|
|
73
|
+
actions: string | string[]
|
|
74
|
+
/** A concrete resource, never `all`. */
|
|
75
|
+
resource: string
|
|
76
|
+
/** Literals and `$principal.` placeholders; must not repeat a scope field. */
|
|
77
|
+
where?: Record<string, unknown>
|
|
78
|
+
scope: CatalogueScope
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface PermissionSpec {
|
|
82
|
+
label?: string
|
|
83
|
+
rules: CatalogueRule[]
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface Catalogue {
|
|
87
|
+
/** Scope kinds, outermost first. Never `'site'`. */
|
|
88
|
+
scopes: string[]
|
|
89
|
+
/** The kind that may own roles; must be `scopes[0]`. Omitted: site roles only. */
|
|
90
|
+
roleOwner?: string
|
|
91
|
+
/** The permissions that gate writing roles and writing grants. */
|
|
92
|
+
gates: { roles: string; grants: string }
|
|
93
|
+
/** `role:` subjects that also count as site-wide grants: `'*'` or a permission list. */
|
|
94
|
+
subjects?: Record<string, '*' | string[]>
|
|
95
|
+
/**
|
|
96
|
+
* The `policy.collections` keys holding role rows and grant rows. The gateway runs the
|
|
97
|
+
* no-escalation check on every write to them. Neither may declare `owner` or `actor`.
|
|
98
|
+
*/
|
|
99
|
+
store?: { roles: string; grants: string }
|
|
100
|
+
/** Names: lower case words joined by `.`, `_` or `-`. */
|
|
101
|
+
permissions: Record<string, PermissionSpec>
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** A role, as stored. `owner == null` (null or missing) is a site role; write `null` explicitly. */
|
|
105
|
+
export interface RoleRow {
|
|
106
|
+
_id: string
|
|
107
|
+
name: string
|
|
108
|
+
permissions: string[]
|
|
109
|
+
owner: string | null
|
|
110
|
+
isArchived?: boolean
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** A grant, as stored. Honoured only once `memberId` is bound; `status` absent or `'ACTIVE'` counts. */
|
|
114
|
+
export interface GrantRow {
|
|
115
|
+
_id?: string
|
|
116
|
+
memberId: string | null
|
|
117
|
+
email?: string | null
|
|
118
|
+
role: string
|
|
119
|
+
scopeKind: ScopeKind
|
|
120
|
+
scopeId: string | null
|
|
121
|
+
status?: string | null
|
|
122
|
+
isArchived?: boolean
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** A grant row as the app's `grants` hook hands it over: plus where it reaches and where it sits. */
|
|
126
|
+
export interface ResolvedGrant extends GrantRow {
|
|
127
|
+
/** Ids the grant reaches, per kind (downward). */
|
|
128
|
+
covers: Record<string, string[]>
|
|
129
|
+
/** Ids the grant sits under, itself included (upward). */
|
|
130
|
+
path: Record<string, string>
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface GrantMaterial {
|
|
134
|
+
roles: RoleRow[]
|
|
135
|
+
grants: ResolvedGrant[]
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface EffectiveGrant {
|
|
139
|
+
id: string | null
|
|
140
|
+
role: string
|
|
141
|
+
roleOwner: string | null
|
|
142
|
+
scope: { kind: ScopeKind; id: string | null }
|
|
143
|
+
path: Record<string, string>
|
|
144
|
+
covers: Record<string, string[]>
|
|
145
|
+
permissions: string[]
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export interface Held {
|
|
149
|
+
scope: { kind: ScopeKind; id: string | null }
|
|
150
|
+
permissions: string[]
|
|
151
|
+
/** Present for a mapped Wix-role subject. */
|
|
152
|
+
source?: 'subject'
|
|
153
|
+
subject?: string
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export type IgnoredReason =
|
|
157
|
+
| 'malformed' | 'notCaller' | 'archived' | 'inactive' | 'unknownScope' | 'badPath'
|
|
158
|
+
| 'roleNotFound' | 'roleArchived' | 'outsideOwner' | 'unknownPermission'
|
|
159
|
+
|
|
160
|
+
export interface Ignored {
|
|
161
|
+
reason: IgnoredReason
|
|
162
|
+
grant: string | null
|
|
163
|
+
role: string | null
|
|
164
|
+
permission?: string
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export interface Problem {
|
|
168
|
+
path: string
|
|
169
|
+
code: string
|
|
170
|
+
value?: unknown
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** What `accessForCaller()` answers, and what the page kit's `fetchRules` may return. */
|
|
174
|
+
export interface AccessForCaller {
|
|
175
|
+
rules: SerialisedRule[]
|
|
176
|
+
grants: {
|
|
177
|
+
held: Held[]
|
|
178
|
+
gates: { roles: string; grants: string }
|
|
179
|
+
roleOwner: string | null
|
|
180
|
+
scopes: string[]
|
|
181
|
+
permissions: string[]
|
|
182
|
+
/** Each held grant's own place, with its path. */
|
|
183
|
+
places: Array<{ kind: ScopeKind; id: string | null; path: Record<string, string> }>
|
|
184
|
+
} | null
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export interface RoleWrite {
|
|
188
|
+
before?: RoleRow | null
|
|
189
|
+
after?: RoleRow | null
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export interface GrantWrite {
|
|
193
|
+
before?: GrantRow | null
|
|
194
|
+
after?: GrantRow | null
|
|
195
|
+
role?: RoleRow | null
|
|
196
|
+
beforeRole?: RoleRow | null
|
|
197
|
+
scope?: ScopeRef | null
|
|
198
|
+
beforeScope?: ScopeRef | null
|
|
48
199
|
}
|
|
49
200
|
|
|
50
201
|
// ---------------------------------------------------------------- principal
|
|
@@ -59,6 +210,8 @@ export interface Principal {
|
|
|
59
210
|
/** Identity resolution itself failed. Distinct from "not logged in". */
|
|
60
211
|
unverified: boolean
|
|
61
212
|
loggedIn?: boolean
|
|
213
|
+
/** 0.6.0: the caller's effective grants. Empty without a catalogue or a grant. */
|
|
214
|
+
grants: EffectiveGrant[]
|
|
62
215
|
}
|
|
63
216
|
|
|
64
217
|
// ---------------------------------------------------------------- envelopes
|
|
@@ -102,3 +255,21 @@ export interface Clause { field: string; op: string; value: unknown }
|
|
|
102
255
|
export declare const SCOPE: { ALL: 'all'; NONE: 'none'; FIELDS: 'fields'; AMBIGUOUS: 'ambiguous' }
|
|
103
256
|
export declare function filterFor(principal: Principal, policy: Policy, action: string, resource: string): { scope: Scope; clauses: Clause[] }
|
|
104
257
|
export declare function applyClauses<Q>(query: Q, clauses: Clause[]): Q
|
|
258
|
+
|
|
259
|
+
// ---------------------------------------------------------------- grants (0.6.0)
|
|
260
|
+
export declare const SITE: 'site'
|
|
261
|
+
/** Run by validatePolicy when the policy has a catalogue. Throws PolicyError. */
|
|
262
|
+
export declare function validateCatalogue(policy: Policy): Catalogue
|
|
263
|
+
/** Which of the hook's grants count for this caller, and why the others do not. */
|
|
264
|
+
export declare function resolveGrants(policy: Policy, principal: Principal, material: GrantMaterial | null): { grants: EffectiveGrant[]; ignored: Ignored[] }
|
|
265
|
+
/** The catalogue compiled over `principal.grants` and mapped subjects. Cached on the principal. */
|
|
266
|
+
export declare function grantRulesFor(principal: Principal, policy: Policy): SerialisedRule[]
|
|
267
|
+
export declare function heldBy(principal: Principal, policy: Policy): Held[]
|
|
268
|
+
export declare function contains(heldScope: { kind: string; id: string | null }, target: ScopeRef | null): boolean
|
|
269
|
+
export declare function holdsAt(held: Held[], permission: string, target: ScopeRef | null): boolean
|
|
270
|
+
export declare function checkRoleWrite(held: Held[], policy: Policy, input: RoleWrite): Ok<null> | Denial
|
|
271
|
+
export declare function checkGrantWrite(held: Held[], policy: Policy, input: GrantWrite): Ok<null> | Denial
|
|
272
|
+
/** Shape problems of a role row, for Apply. Empty means well-formed. */
|
|
273
|
+
export declare function checkRoleRow(row: unknown, policy: Policy): Problem[]
|
|
274
|
+
/** Shape problems of a grant row, for Apply; with `roles`, also a missing or archived role. */
|
|
275
|
+
export declare function checkGrantRow(row: unknown, policy: Policy, roles?: RoleRow[]): Problem[]
|