@spacefast/common 0.0.12 → 0.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. package/dist/agents/client-registry.d.ts +22 -0
  2. package/dist/agents/client-registry.js +41 -0
  3. package/dist/agents/connect-targets.d.ts +51 -6
  4. package/dist/agents/connect-targets.js +93 -28
  5. package/dist/brand.d.ts +0 -11
  6. package/dist/brand.js +0 -20
  7. package/dist/config/domains.d.ts +15 -6
  8. package/dist/config/domains.js +24 -10
  9. package/dist/config/postgres-budget.d.ts +3 -0
  10. package/dist/config/postgres-budget.js +6 -1
  11. package/dist/config/postgres-budget.json +2 -1
  12. package/dist/contracts/abuse.js +1 -1
  13. package/dist/contracts/access.d.ts +486 -1196
  14. package/dist/contracts/access.js +323 -1054
  15. package/dist/contracts/activity.d.ts +1 -1
  16. package/dist/contracts/activity.js +11 -15
  17. package/dist/contracts/api-keys.d.ts +16 -0
  18. package/dist/contracts/api-keys.js +11 -9
  19. package/dist/contracts/archives.d.ts +1 -2
  20. package/dist/contracts/archives.js +15 -17
  21. package/dist/contracts/beta.js +1 -1
  22. package/dist/contracts/builds.js +14 -14
  23. package/dist/contracts/channels.js +2 -2
  24. package/dist/contracts/comments.d.ts +143 -99
  25. package/dist/contracts/comments.js +194 -79
  26. package/dist/contracts/common.d.ts +12 -12
  27. package/dist/contracts/common.js +33 -30
  28. package/dist/contracts/continuation.js +5 -5
  29. package/dist/contracts/countries.js +2 -7
  30. package/dist/contracts/data-source-routes.d.ts +20 -0
  31. package/dist/contracts/data-source-routes.js +15 -0
  32. package/dist/contracts/device-auth.d.ts +13 -9
  33. package/dist/contracts/device-auth.js +12 -12
  34. package/dist/contracts/docs.d.ts +10 -10
  35. package/dist/contracts/domains.js +39 -33
  36. package/dist/contracts/enums.d.ts +4 -14
  37. package/dist/contracts/enums.js +3 -10
  38. package/dist/contracts/error-code-meta.d.ts +122 -56
  39. package/dist/contracts/error-code-meta.js +43 -19
  40. package/dist/contracts/error-codes.d.ts +7 -4
  41. package/dist/contracts/error-codes.js +48 -24
  42. package/dist/contracts/events.d.ts +22 -15
  43. package/dist/contracts/events.js +33 -5
  44. package/dist/contracts/execution.d.ts +238 -0
  45. package/dist/contracts/execution.js +309 -0
  46. package/dist/contracts/feature-lifecycle.d.ts +39 -188
  47. package/dist/contracts/feature-lifecycle.js +52 -196
  48. package/dist/contracts/features.d.ts +13 -115
  49. package/dist/contracts/features.js +5 -35
  50. package/dist/contracts/functions.d.ts +597 -0
  51. package/dist/contracts/functions.js +475 -0
  52. package/dist/contracts/grants.d.ts +1175 -0
  53. package/dist/contracts/grants.js +783 -0
  54. package/dist/contracts/ids.d.ts +7 -5
  55. package/dist/contracts/ids.js +7 -7
  56. package/dist/contracts/internal.js +2 -2
  57. package/dist/contracts/mcp.d.ts +17 -556
  58. package/dist/contracts/mcp.js +9 -103
  59. package/dist/contracts/me.js +3 -4
  60. package/dist/contracts/notifications.d.ts +108 -0
  61. package/dist/contracts/notifications.js +54 -0
  62. package/dist/contracts/oauth-resources.d.ts +22 -5
  63. package/dist/contracts/oauth-resources.js +23 -2
  64. package/dist/contracts/operations.d.ts +0 -48
  65. package/dist/contracts/operations.js +0 -19
  66. package/dist/contracts/pages.d.ts +10 -14
  67. package/dist/contracts/pages.js +17 -21
  68. package/dist/contracts/plan-policy.d.ts +1 -8
  69. package/dist/contracts/plan-policy.js +1 -4
  70. package/dist/contracts/platform.d.ts +78 -30
  71. package/dist/contracts/platform.js +69 -20
  72. package/dist/contracts/problem-document.d.ts +14 -0
  73. package/dist/contracts/problem-document.js +35 -0
  74. package/dist/contracts/push-new.d.ts +41 -2
  75. package/dist/contracts/push-new.js +4 -0
  76. package/dist/contracts/quotas.d.ts +0 -1
  77. package/dist/contracts/quotas.js +0 -5
  78. package/dist/contracts/repository-connections.d.ts +1 -1
  79. package/dist/contracts/resources.d.ts +16 -71
  80. package/dist/contracts/resources.js +13 -16
  81. package/dist/contracts/runtime-api.d.ts +666 -303
  82. package/dist/contracts/runtime-api.js +272 -113
  83. package/dist/contracts/runtime-app.d.ts +168 -0
  84. package/dist/contracts/runtime-app.js +42 -0
  85. package/dist/contracts/runtime-db.d.ts +424 -0
  86. package/dist/contracts/runtime-db.js +108 -0
  87. package/dist/contracts/runtime-storage.d.ts +120 -0
  88. package/dist/contracts/runtime-storage.js +40 -0
  89. package/dist/contracts/sf-config-v1.d.ts +54 -1
  90. package/dist/contracts/sf-config-v1.js +2 -2
  91. package/dist/contracts/sites.d.ts +6 -0
  92. package/dist/contracts/sites.js +30 -11
  93. package/dist/contracts/space-config.d.ts +91 -121
  94. package/dist/contracts/space-config.js +464 -42
  95. package/dist/contracts/spaces.d.ts +300 -171
  96. package/dist/contracts/spaces.js +128 -98
  97. package/dist/contracts/superadmin-emails.d.ts +2 -2
  98. package/dist/contracts/superadmin-spaces.d.ts +26 -130
  99. package/dist/contracts/superadmin-spaces.js +22 -0
  100. package/dist/contracts/superadmin-tenants.js +4 -4
  101. package/dist/contracts/superadmin.d.ts +4 -0
  102. package/dist/contracts/superadmin.js +14 -1
  103. package/dist/contracts/tags.d.ts +6 -6
  104. package/dist/contracts/tags.js +1 -1
  105. package/dist/contracts/teams.d.ts +9 -9
  106. package/dist/contracts/teams.js +25 -16
  107. package/dist/contracts/theme-json.js +1 -1
  108. package/dist/contracts/transfers.d.ts +0 -1
  109. package/dist/contracts/transfers.js +4 -4
  110. package/dist/contracts/variables.js +3 -3
  111. package/dist/contracts/zero.d.ts +384 -596
  112. package/dist/contracts/zero.js +167 -299
  113. package/dist/dashboard-paths/index.d.ts +18 -3
  114. package/dist/dashboard-paths/index.js +19 -0
  115. package/dist/docs/agent-handoff-document.d.ts +2 -2
  116. package/dist/docs/agent-handoff-document.js +8 -7
  117. package/dist/docs/agent-prose.d.ts +22 -3
  118. package/dist/docs/agent-prose.js +227 -55
  119. package/dist/docs/agent-setup.d.ts +14 -11
  120. package/dist/docs/agent-setup.js +289 -61
  121. package/dist/docs/agent-solutions.d.ts +6 -6
  122. package/dist/docs/agent-solutions.js +24 -22
  123. package/dist/docs/catalog.d.ts +53 -98
  124. package/dist/docs/catalog.js +90 -117
  125. package/dist/docs/error-docs.js +304 -236
  126. package/dist/docs/skill-distribution.d.ts +2 -0
  127. package/dist/docs/skill-distribution.js +7 -4
  128. package/dist/docs/skills.d.ts +546 -0
  129. package/dist/docs/skills.js +340 -0
  130. package/dist/utils/auth-redirect.d.ts +1 -3
  131. package/dist/utils/auth-redirect.js +1 -21
  132. package/dist/utils/browser-credential.d.ts +19 -0
  133. package/dist/utils/browser-credential.js +62 -0
  134. package/dist/utils/build-settings.d.ts +2 -0
  135. package/dist/utils/build-settings.js +61 -9
  136. package/dist/utils/comment-avatars.d.ts +7 -0
  137. package/dist/utils/comment-avatars.js +42 -0
  138. package/dist/utils/content-type.d.ts +3 -3
  139. package/dist/utils/content-type.js +38 -61
  140. package/dist/utils/credential-policy.d.ts +1 -1
  141. package/dist/utils/credential-policy.js +4 -0
  142. package/dist/utils/domain-diagnostics.d.ts +5 -5
  143. package/dist/utils/domain-diagnostics.js +21 -10
  144. package/dist/utils/egress-policy.fixtures.json +1 -1
  145. package/dist/utils/grants.d.ts +53 -0
  146. package/dist/utils/grants.js +160 -0
  147. package/dist/utils/local-space-state.d.ts +78 -4
  148. package/dist/utils/local-space-state.js +384 -82
  149. package/dist/utils/one-shot-replay.d.ts +14 -0
  150. package/dist/utils/one-shot-replay.js +21 -0
  151. package/dist/utils/page-preview.d.ts +7 -0
  152. package/dist/utils/page-preview.js +9 -0
  153. package/dist/utils/pages.d.ts +2 -5
  154. package/dist/utils/pages.js +64 -33
  155. package/dist/utils/publish-form-data.d.ts +22 -0
  156. package/dist/utils/publish-form-data.js +26 -0
  157. package/dist/utils/publish-policy.d.ts +34 -4
  158. package/dist/utils/publish-policy.js +149 -62
  159. package/dist/utils/query-keys.d.ts +8 -10
  160. package/dist/utils/query-keys.js +14 -10
  161. package/dist/utils/runtime-paths.d.ts +3 -0
  162. package/dist/utils/runtime-paths.js +7 -0
  163. package/dist/utils/secure-local-file.d.ts +73 -0
  164. package/dist/utils/secure-local-file.js +1373 -0
  165. package/dist/utils/space-config.d.ts +17 -4
  166. package/dist/utils/space-config.js +151 -8
  167. package/dist/utils/static-runtime-policy.d.ts +5 -0
  168. package/dist/utils/static-runtime-policy.js +54 -10
  169. package/dist/utils/storage-policy.d.ts +20 -0
  170. package/dist/utils/storage-policy.fixtures.json +174 -0
  171. package/dist/utils/storage-policy.js +193 -0
  172. package/dist/utils/upload-session.d.ts +15 -1
  173. package/dist/utils/upload-session.js +68 -2
  174. package/dist/utils/version-file-browser.d.ts +13 -0
  175. package/dist/utils/version-file-browser.js +59 -0
  176. package/package.json +20 -1
  177. package/dist/contracts/mounts.d.ts +0 -142
  178. package/dist/contracts/mounts.js +0 -56
  179. package/dist/utils/access-grant.d.ts +0 -14
  180. package/dist/utils/access-grant.js +0 -88
  181. package/dist/utils/access-match.d.ts +0 -46
  182. package/dist/utils/access-match.fixtures.json +0 -513
  183. package/dist/utils/access-match.js +0 -312
  184. package/dist/utils/access-verdict.fixtures.json +0 -421
  185. package/dist/utils/asset-fingerprint.d.ts +0 -53
  186. package/dist/utils/asset-fingerprint.js +0 -574
  187. package/dist/utils/sf-config-v1.d.ts +0 -2
  188. package/dist/utils/sf-config-v1.fixtures.json +0 -9
  189. package/dist/utils/sf-config-v1.js +0 -551
@@ -1,88 +0,0 @@
1
- // `sf access grant` and the dashboard's Grant access card share one canonical
2
- // pair: an authenticated admission allow plus an anonymous fallback challenge.
3
- // Repeated grants widen both rules' OR-list. The split is essential under
4
- // first-match evaluation: the admission can pass before managed challenges,
5
- // while the fallback closes otherwise-public traffic after those challenges.
6
- export const ACCESS_GRANT_GATE_RULE_ID = "access-grant-gate";
7
- export const ACCESS_GRANT_ADMISSION_RULE_ID = "access-grant-admission";
8
- export function withAccessGrantGate(rules, grant) {
9
- // Raw access writes replace only the unmanaged lane. GET/PUT responses may
10
- // include server-owned managed blocks, but sending those blocks back would
11
- // be rejected and could let a client accidentally claim their ownership.
12
- // Reserved access-grant rules are rebuilt as one canonical pair below.
13
- const unmanagedRules = rules.filter((rule) => rule.managedBy === undefined &&
14
- rule.id !== ACCESS_GRANT_ADMISSION_RULE_ID &&
15
- rule.id !== ACCESS_GRANT_GATE_RULE_ID);
16
- const existingRequiredGrants = rules.find((rule) => rule.id === ACCESS_GRANT_ADMISSION_RULE_ID)
17
- ?.auth?.requiredGrants;
18
- const fallbackRequiredGrants = rules.find((rule) => rule.id === ACCESS_GRANT_GATE_RULE_ID)?.auth
19
- ?.requiredGrants;
20
- const requiredGrants = [
21
- ...new Set([...(existingRequiredGrants ?? fallbackRequiredGrants ?? []), grant]),
22
- ];
23
- return [
24
- ...unmanagedRules,
25
- {
26
- id: ACCESS_GRANT_ADMISSION_RULE_ID,
27
- match: {},
28
- effect: "allow",
29
- auth: { requiredGrants },
30
- reasonCode: "identity_grant_admitted",
31
- },
32
- {
33
- id: ACCESS_GRANT_GATE_RULE_ID,
34
- match: {},
35
- effect: "challenge",
36
- auth: { requiredGrants },
37
- reasonCode: "identity_grant_required",
38
- message: "Sign in with an approved identity to continue.",
39
- },
40
- ];
41
- }
42
- export function withoutAccessGrantRule(rules, selectedIndex) {
43
- const selectedRule = rules[selectedIndex];
44
- const removesAccessGrant = selectedRule?.id === ACCESS_GRANT_ADMISSION_RULE_ID ||
45
- selectedRule?.id === ACCESS_GRANT_GATE_RULE_ID;
46
- return rules.filter((rule, index) => rule.managedBy === undefined &&
47
- (removesAccessGrant
48
- ? rule.id !== ACCESS_GRANT_ADMISSION_RULE_ID && rule.id !== ACCESS_GRANT_GATE_RULE_ID
49
- : index !== selectedIndex));
50
- }
51
- export function isAccessGrantAdmissionRule(rule) {
52
- return (rule.id === ACCESS_GRANT_ADMISSION_RULE_ID &&
53
- rule.effect === "allow" &&
54
- Object.keys(rule.match).length === 0 &&
55
- rule.auth !== undefined);
56
- }
57
- export function isAccessGrantFallbackRule(rule) {
58
- return (rule.id === ACCESS_GRANT_GATE_RULE_ID &&
59
- rule.effect === "challenge" &&
60
- Object.keys(rule.match).length === 0 &&
61
- rule.auth !== undefined);
62
- }
63
- // The admission allow protects approved identities without preempting the
64
- // existing password/share/service challenge. The final fallback gate protects
65
- // public fallthrough. A terminal rule from an earlier effective lane can still
66
- // stop evaluation before admission; report that explicitly instead of claiming
67
- // the space is simply gated.
68
- export function accessGrantExposure(rules) {
69
- const gateIndex = rules.findIndex(isAccessGrantFallbackRule);
70
- const admissionIndex = rules.findIndex(isAccessGrantAdmissionRule);
71
- const earlierRules = gateIndex === -1 ? rules : rules.slice(0, gateIndex);
72
- const rulesBeforeAdmission = admissionIndex === -1 ? earlierRules : rules.slice(0, admissionIndex);
73
- const precedingTerminalRules = rulesBeforeAdmission.filter((rule) => rule.effect === "challenge" || (rule.effect === "deny" && rule.auth === undefined)).length;
74
- const earlierAnonymousAllowRules = earlierRules.filter((rule) => rule.effect === "allow" && !rule.auth).length;
75
- const earlierManagedAccessRules = earlierRules.filter((rule) => rule.managedBy !== undefined && rule.effect === "allow").length;
76
- return {
77
- anonymousAccess: precedingTerminalRules > 0
78
- ? "shadowed"
79
- : earlierAnonymousAllowRules > 0
80
- ? "partly_public"
81
- : earlierManagedAccessRules > 0
82
- ? "gated_with_exceptions"
83
- : "gated",
84
- earlierAnonymousAllowRules,
85
- earlierManagedAccessRules,
86
- precedingTerminalRules,
87
- };
88
- }
@@ -1,46 +0,0 @@
1
- export declare function filterGrantsByNamespace(grants: string[], namespaces: string[]): string[];
2
- export declare function grantGlobMatches(pattern: string, grant: string): boolean;
3
- export declare function grantsIntersect(grants: string[], requiredGrants: string[]): boolean;
4
- export declare function requiredGrantsForRule(rule: {
5
- managedBy?: string | undefined;
6
- auth?: {
7
- requiredGrants: string[];
8
- } | undefined;
9
- }): string[];
10
- export declare function grantsSatisfyRule(input: {
11
- grants: string[];
12
- requiredGrants: string[];
13
- grantNamespaces: string[];
14
- }): boolean;
15
- export declare function canonicalizeHost(host: string): string;
16
- export declare function hostGlobMatches(pattern: string, host: string): boolean;
17
- export declare function hostTemplateMatches(template: string, host: string): boolean;
18
- export declare function pathGlobMatches(pattern: string, path: string): boolean;
19
- export declare function agentMatches(needle: string, agent: string): boolean;
20
- export declare function ipInCidr(ip: string, cidr: string): boolean;
21
- export declare function ipInAnyCidr(ip: string, cidrs: string[]): boolean;
22
- export type RuleMatchContext = {
23
- host: string;
24
- path: string;
25
- channel?: string | undefined;
26
- ip?: string | undefined;
27
- agent?: string | undefined;
28
- country?: string | undefined;
29
- headers?: Record<string, string> | undefined;
30
- };
31
- export type RuleMatchInput = {
32
- host?: string | undefined;
33
- hostPattern?: string | undefined;
34
- hostTemplate?: string | undefined;
35
- pathPattern?: string | undefined;
36
- channel?: string | undefined;
37
- ipCidrs?: string[] | undefined;
38
- agent?: string | undefined;
39
- country?: string | undefined;
40
- countryNotIn?: string[] | undefined;
41
- header?: {
42
- name: string;
43
- value: string;
44
- } | undefined;
45
- };
46
- export declare function ruleMatchApplies(match: RuleMatchInput, context: RuleMatchContext): boolean;
@@ -1,513 +0,0 @@
1
- {
2
- "namespaceFilter": [
3
- {
4
- "name": "platform namespaces keep platform grants",
5
- "grants": ["user:usr_1", "email:carol@acme.com", "team:team_1:member"],
6
- "namespaces": [
7
- "team:",
8
- "sub-team:",
9
- "user:",
10
- "email:",
11
- "space:",
12
- "link:",
13
- "invite:",
14
- "svc:",
15
- "sso:"
16
- ],
17
- "expected": ["user:usr_1", "email:carol@acme.com", "team:team_1:member"]
18
- },
19
- {
20
- "name": "external key drops everything outside its ext binding",
21
- "grants": ["ext:acn_1:wc-subscriber", "team:team_1:owner", "user:usr_1", "email:x@y.z"],
22
- "namespaces": ["ext:acn_1:"],
23
- "expected": ["ext:acn_1:wc-subscriber"]
24
- },
25
- {
26
- "name": "an external token minting team grants is fully dropped",
27
- "grants": ["team:team_1:owner", "team:team_1:admin"],
28
- "namespaces": ["ext:acn_1:"],
29
- "expected": []
30
- },
31
- {
32
- "name": "local pw key signs only pw grants",
33
- "grants": ["pw:space-password", "team:team_1:viewer", "email:a@b.c"],
34
- "namespaces": ["pw:"],
35
- "expected": ["pw:space-password"]
36
- },
37
- {
38
- "name": "prefix match is a plain startsWith, not a segment match",
39
- "grants": ["sub-team:sub_1:member", "team:team_1:member"],
40
- "namespaces": ["team:"],
41
- "expected": ["team:team_1:member"]
42
- },
43
- {
44
- "name": "empty namespace entries never match",
45
- "grants": ["user:usr_1"],
46
- "namespaces": [""],
47
- "expected": []
48
- },
49
- {
50
- "name": "email-domain namespace is dead: nothing carries it, nothing keeps it",
51
- "grants": ["email-domain:acme.com"],
52
- "namespaces": [
53
- "team:",
54
- "sub-team:",
55
- "user:",
56
- "email:",
57
- "space:",
58
- "link:",
59
- "invite:",
60
- "svc:",
61
- "sso:"
62
- ],
63
- "expected": []
64
- },
65
- {
66
- "name": "empty grant strings are dropped",
67
- "grants": ["", "user:usr_1"],
68
- "namespaces": ["user:"],
69
- "expected": ["user:usr_1"]
70
- }
71
- ],
72
- "glob": [
73
- {
74
- "pattern": "email:carol@acme.com",
75
- "grant": "email:carol@acme.com",
76
- "expected": true
77
- },
78
- {
79
- "pattern": "email:carol@acme.com",
80
- "grant": "email:mallory@acme.com",
81
- "expected": false
82
- },
83
- {
84
- "pattern": "email:*@acme.com",
85
- "grant": "email:carol@acme.com",
86
- "expected": true
87
- },
88
- {
89
- "pattern": "email:*@acme.com",
90
- "grant": "email:carol@evil.com",
91
- "expected": false
92
- },
93
- {
94
- "pattern": "email:*@acme.com",
95
- "grant": "email:carol@sub.acme.com",
96
- "expected": false
97
- },
98
- {
99
- "pattern": "email:*acme.com",
100
- "grant": "email:carol@sub.acme.com",
101
- "expected": true
102
- },
103
- {
104
- "pattern": "email:*@acme.com",
105
- "grant": "email:@acme.com",
106
- "expected": true
107
- },
108
- {
109
- "pattern": "team:*",
110
- "grant": "team:team_1:member",
111
- "expected": true
112
- },
113
- {
114
- "pattern": "team:team_1:*",
115
- "grant": "team:team_1:viewer",
116
- "expected": true
117
- },
118
- {
119
- "pattern": "team:team_1:*",
120
- "grant": "team:team_2:viewer",
121
- "expected": false
122
- },
123
- {
124
- "pattern": "user:*",
125
- "grant": "user:usr_1",
126
- "expected": true
127
- },
128
- {
129
- "pattern": "user:*",
130
- "grant": "email:x@y.z",
131
- "expected": false
132
- },
133
- {
134
- "pattern": "space:spc_1:*",
135
- "grant": "space:spc_1:commenter",
136
- "expected": true
137
- },
138
- {
139
- "pattern": "*",
140
- "grant": "anything:at:all",
141
- "expected": true
142
- },
143
- {
144
- "pattern": "pw:space-password",
145
- "grant": "pw:space-password",
146
- "expected": true
147
- },
148
- {
149
- "pattern": "pw:space-password",
150
- "grant": "pw:other-rule",
151
- "expected": false
152
- },
153
- {
154
- "pattern": "email:*@a*.com",
155
- "grant": "email:x@acme.com",
156
- "expected": true
157
- },
158
- {
159
- "pattern": "email:*@a*.com",
160
- "grant": "email:x@bcme.com",
161
- "expected": false
162
- },
163
- {
164
- "pattern": "email:a.b@acme.com",
165
- "grant": "email:aXb@acme.com",
166
- "expected": false
167
- },
168
- {
169
- "pattern": "svc:stk_1",
170
- "grant": "svc:stk_1",
171
- "expected": true
172
- },
173
- {
174
- "pattern": "link:lnk_*",
175
- "grant": "link:lnk_abc",
176
- "expected": true
177
- },
178
- {
179
- "pattern": "",
180
- "grant": "user:usr_1",
181
- "expected": false
182
- }
183
- ],
184
- "intersect": [
185
- {
186
- "name": "single exact hit",
187
- "grants": ["user:usr_1", "email:carol@acme.com"],
188
- "requiredGrants": ["email:carol@acme.com"],
189
- "expected": true
190
- },
191
- {
192
- "name": "no overlap",
193
- "grants": ["user:usr_1", "team:team_1:member"],
194
- "requiredGrants": ["email:*@acme.com", "link:lnk_1"],
195
- "expected": false
196
- },
197
- {
198
- "name": "glob run crosses separators",
199
- "grants": ["team:team_1:member"],
200
- "requiredGrants": ["team:*:member"],
201
- "expected": true
202
- },
203
- {
204
- "name": "any-of over requiredGrants",
205
- "grants": ["invite:sin_1"],
206
- "requiredGrants": ["email:x@y.z", "invite:sin_1", "team:team_1:viewer"],
207
- "expected": true
208
- },
209
- {
210
- "name": "empty grants never pass",
211
- "grants": [],
212
- "requiredGrants": ["user:*"],
213
- "expected": false
214
- },
215
- {
216
- "name": "empty requiredGrants never pass",
217
- "grants": ["user:usr_1"],
218
- "requiredGrants": [],
219
- "expected": false
220
- },
221
- {
222
- "name": "empty-string entries are ignored on both sides",
223
- "grants": [""],
224
- "requiredGrants": [""],
225
- "expected": false
226
- },
227
- {
228
- "name": "concrete grant does not glob against a concrete requirement",
229
- "grants": ["email:carol@acme.com"],
230
- "requiredGrants": ["email:carol@acme.co"],
231
- "expected": false
232
- }
233
- ],
234
- "satisfy": [
235
- {
236
- "name": "platform token passes an email-domain wall",
237
- "grants": ["user:usr_1", "email:carol@acme.com", "team:team_1:member"],
238
- "grantNamespaces": [
239
- "team:",
240
- "sub-team:",
241
- "user:",
242
- "email:",
243
- "space:",
244
- "link:",
245
- "invite:",
246
- "svc:",
247
- "sso:"
248
- ],
249
- "requiredGrants": ["email:*@acme.com"],
250
- "expected": true
251
- },
252
- {
253
- "name": "external token cannot satisfy a team wall (namespace drop first)",
254
- "grants": ["team:team_1:member"],
255
- "grantNamespaces": ["ext:acn_1:"],
256
- "requiredGrants": ["team:team_1:member"],
257
- "expected": false
258
- },
259
- {
260
- "name": "local pw token satisfies exactly its wall",
261
- "grants": ["pw:space-password"],
262
- "grantNamespaces": ["pw:"],
263
- "requiredGrants": ["pw:space-password"],
264
- "expected": true
265
- },
266
- {
267
- "name": "pw token cannot satisfy an identity wall",
268
- "grants": ["pw:space-password"],
269
- "grantNamespaces": ["pw:"],
270
- "requiredGrants": ["email:*@acme.com", "team:team_1:viewer"],
271
- "expected": false
272
- },
273
- {
274
- "name": "external token satisfies its own owner-defined tag",
275
- "grants": ["ext:acn_1:wc-subscriber"],
276
- "grantNamespaces": ["ext:acn_1:"],
277
- "requiredGrants": ["ext:acn_1:wc-subscriber"],
278
- "expected": true
279
- },
280
- {
281
- "name": "external token minting team:* wildcard grants fails the namespace filter",
282
- "grants": [
283
- "ext:acn_1:wc-subscriber",
284
- "team:*",
285
- "team:team_1:owner",
286
- "user:usr_1",
287
- "email:carol@acme.com"
288
- ],
289
- "grantNamespaces": ["ext:acn_1:"],
290
- "requiredGrants": ["team:*"],
291
- "expected": false
292
- },
293
- {
294
- "name": "external token cannot cross into another connection's ext namespace",
295
- "grants": ["ext:acn_2:wc-subscriber"],
296
- "grantNamespaces": ["ext:acn_1:"],
297
- "requiredGrants": ["ext:acn_2:wc-subscriber"],
298
- "expected": false
299
- },
300
- {
301
- "name": "sso token passes the connection audience and its verified email glob",
302
- "grants": ["sso:acn_9", "email:carol@acme.com"],
303
- "grantNamespaces": [
304
- "team:",
305
- "sub-team:",
306
- "user:",
307
- "email:",
308
- "space:",
309
- "link:",
310
- "invite:",
311
- "svc:",
312
- "sso:"
313
- ],
314
- "requiredGrants": ["email:*@acme.com"],
315
- "expected": true
316
- },
317
- {
318
- "name": "same-space grant cannot satisfy an identity-bound reviewer rule",
319
- "grants": ["space:spc_review:viewer"],
320
- "grantNamespaces": ["email:", "space:"],
321
- "requiredGrants": ["email:reviewer.a@example.com"],
322
- "expected": false
323
- },
324
- {
325
- "name": "the exact reviewer identity satisfies its identity-bound rule",
326
- "grants": ["email:reviewer.a@example.com", "space:spc_review:viewer"],
327
- "grantNamespaces": ["email:", "space:"],
328
- "requiredGrants": ["email:reviewer.a@example.com"],
329
- "expected": true
330
- },
331
- {
332
- "name": "a different reviewer remains denied despite a same-space grant",
333
- "grants": ["email:reviewer.b@example.com", "space:spc_review:viewer"],
334
- "grantNamespaces": ["email:", "space:"],
335
- "requiredGrants": ["email:reviewer.a@example.com"],
336
- "expected": false
337
- }
338
- ],
339
- "pathGlob": [
340
- {
341
- "pattern": "",
342
- "path": "/anything",
343
- "expected": true
344
- },
345
- {
346
- "pattern": "/x.html",
347
- "path": "/x.html",
348
- "expected": true
349
- },
350
- {
351
- "pattern": "/x.html",
352
- "path": "/x.htm",
353
- "expected": false
354
- },
355
- {
356
- "pattern": "/docs/**",
357
- "path": "/docs/",
358
- "expected": true
359
- },
360
- {
361
- "pattern": "/docs/**",
362
- "path": "/docs/a/b/c.html",
363
- "expected": true
364
- },
365
- {
366
- "pattern": "/docs/**",
367
- "path": "/docs",
368
- "expected": false
369
- },
370
- {
371
- "pattern": "/docs/*",
372
- "path": "/docs/a.html",
373
- "expected": true
374
- },
375
- {
376
- "pattern": "/docs/*",
377
- "path": "/docs/a/b.html",
378
- "expected": false
379
- },
380
- {
381
- "pattern": "/docs/*",
382
- "path": "/docs/",
383
- "expected": true
384
- },
385
- {
386
- "pattern": "/report/**",
387
- "path": "/report/q2/deck.pdf",
388
- "expected": true
389
- },
390
- {
391
- "pattern": "/report/**",
392
- "path": "/reports/q2.pdf",
393
- "expected": false
394
- },
395
- {
396
- "pattern": "/*.html",
397
- "path": "/index.html",
398
- "expected": true
399
- },
400
- {
401
- "pattern": "/*.html",
402
- "path": "/a/index.html",
403
- "expected": false
404
- },
405
- {
406
- "pattern": "/**",
407
- "path": "/",
408
- "expected": true
409
- },
410
- {
411
- "pattern": "/**",
412
- "path": "/deep/path/file.txt",
413
- "expected": true
414
- },
415
- {
416
- "pattern": "/a+b/**",
417
- "path": "/a+b/x",
418
- "expected": true
419
- },
420
- {
421
- "pattern": "/a.b/**",
422
- "path": "/axb/x",
423
- "expected": false
424
- }
425
- ],
426
- "cidr": [
427
- {
428
- "ip": "1.2.3.4",
429
- "cidr": "1.2.3.0/24",
430
- "expected": true
431
- },
432
- {
433
- "ip": "1.2.4.4",
434
- "cidr": "1.2.3.0/24",
435
- "expected": false
436
- },
437
- {
438
- "ip": "1.2.3.4",
439
- "cidr": "1.2.3.4",
440
- "expected": true
441
- },
442
- {
443
- "ip": "1.2.3.4",
444
- "cidr": "1.2.3.5",
445
- "expected": false
446
- },
447
- {
448
- "ip": "10.0.0.1",
449
- "cidr": "10.0.0.0/8",
450
- "expected": true
451
- },
452
- {
453
- "ip": "10.128.0.1",
454
- "cidr": "10.0.0.0/9",
455
- "expected": false
456
- },
457
- {
458
- "ip": "10.127.255.255",
459
- "cidr": "10.0.0.0/9",
460
- "expected": true
461
- },
462
- {
463
- "ip": "1.2.3.4",
464
- "cidr": "0.0.0.0/0",
465
- "expected": true
466
- },
467
- {
468
- "ip": "1.2.3.4",
469
- "cidr": "1.2.3.0/33",
470
- "expected": false
471
- },
472
- {
473
- "ip": "1.2.3.4",
474
- "cidr": "",
475
- "expected": false
476
- },
477
- {
478
- "ip": "not-an-ip",
479
- "cidr": "1.2.3.0/24",
480
- "expected": false
481
- },
482
- {
483
- "ip": "2001:db8::1",
484
- "cidr": "2001:db8::/32",
485
- "expected": true
486
- },
487
- {
488
- "ip": "2001:db9::1",
489
- "cidr": "2001:db8::/32",
490
- "expected": false
491
- },
492
- {
493
- "ip": "2001:db8::1",
494
- "cidr": "1.2.3.0/24",
495
- "expected": false
496
- },
497
- {
498
- "ip": "1.2.3.4",
499
- "cidr": "2001:db8::/32",
500
- "expected": false
501
- },
502
- {
503
- "ip": "::ffff:1.2.3.4",
504
- "cidr": "::ffff:1.2.3.0/120",
505
- "expected": true
506
- },
507
- {
508
- "ip": "fe80::aaaa:bbbb",
509
- "cidr": "fe80::/10",
510
- "expected": true
511
- }
512
- ]
513
- }