@uptime.app/contracts 3.0.54 → 4.0.0-rc.2

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 (258) hide show
  1. package/dist/cjs/app-hack/app-hack-metadata.d.ts +1 -0
  2. package/dist/cjs/app-hack/app-hack-metadata.d.ts.map +1 -1
  3. package/dist/cjs/cms-hack/cms-searchable-hack.d.ts +2 -0
  4. package/dist/cjs/cms-hack/cms-searchable-hack.d.ts.map +1 -1
  5. package/dist/cjs/draft-hack/draft-hack.d.ts +2 -0
  6. package/dist/cjs/draft-hack/draft-hack.d.ts.map +1 -1
  7. package/dist/cjs/draft-hack-generation/draft-hack-generation.d.ts +2 -0
  8. package/dist/cjs/draft-hack-generation/draft-hack-generation.d.ts.map +1 -1
  9. package/dist/cjs/enriched-hack/enriched-hack.d.ts +2 -0
  10. package/dist/cjs/enriched-hack/enriched-hack.d.ts.map +1 -1
  11. package/dist/cjs/flashcard/flashcard.d.ts +3 -1
  12. package/dist/cjs/flashcard/flashcard.d.ts.map +1 -1
  13. package/dist/cjs/hack/hack.d.ts +3 -0
  14. package/dist/cjs/hack/hack.d.ts.map +1 -1
  15. package/dist/cjs/hack-mapping/app-hack-metadata.d.ts.map +1 -1
  16. package/dist/cjs/hack-mapping/app-hack-metadata.js +1 -0
  17. package/dist/cjs/hack-mapping/app-hack-metadata.js.map +1 -1
  18. package/dist/cjs/identity-provider/identity-provider.d.ts +0 -4
  19. package/dist/cjs/identity-provider/identity-provider.d.ts.map +1 -1
  20. package/dist/cjs/index.d.ts +2 -0
  21. package/dist/cjs/index.d.ts.map +1 -1
  22. package/dist/cjs/index.js +2 -0
  23. package/dist/cjs/index.js.map +1 -1
  24. package/dist/cjs/interest/interest.d.ts +1 -0
  25. package/dist/cjs/interest/interest.d.ts.map +1 -1
  26. package/dist/cjs/knowledge-source/knowledge-source.d.ts +2 -0
  27. package/dist/cjs/knowledge-source/knowledge-source.d.ts.map +1 -1
  28. package/dist/cjs/pending-hack/pending-hack.d.ts +2 -0
  29. package/dist/cjs/pending-hack/pending-hack.d.ts.map +1 -1
  30. package/dist/cjs/spark/spark.d.ts +1 -1
  31. package/dist/cjs/spark/spark.d.ts.map +1 -1
  32. package/dist/cjs/topics/primary-topic-mapping.d.ts +11 -0
  33. package/dist/cjs/topics/primary-topic-mapping.d.ts.map +1 -0
  34. package/dist/cjs/topics/primary-topic-mapping.js +119 -0
  35. package/dist/cjs/topics/primary-topic-mapping.js.map +1 -0
  36. package/dist/cjs/topics/primary-topic.d.ts +4 -0
  37. package/dist/cjs/topics/primary-topic.d.ts.map +1 -0
  38. package/dist/cjs/topics/primary-topic.js +3 -0
  39. package/dist/cjs/topics/primary-topic.js.map +1 -0
  40. package/dist/esm/app-hack/app-hack-metadata.d.ts +1 -0
  41. package/dist/esm/app-hack/app-hack-metadata.d.ts.map +1 -1
  42. package/dist/esm/cms-hack/cms-searchable-hack.d.ts +2 -0
  43. package/dist/esm/cms-hack/cms-searchable-hack.d.ts.map +1 -1
  44. package/dist/esm/draft-hack/draft-hack.d.ts +2 -0
  45. package/dist/esm/draft-hack/draft-hack.d.ts.map +1 -1
  46. package/dist/esm/draft-hack-generation/draft-hack-generation.d.ts +2 -0
  47. package/dist/esm/draft-hack-generation/draft-hack-generation.d.ts.map +1 -1
  48. package/dist/esm/enriched-hack/enriched-hack.d.ts +2 -0
  49. package/dist/esm/enriched-hack/enriched-hack.d.ts.map +1 -1
  50. package/dist/esm/flashcard/flashcard.d.ts +3 -1
  51. package/dist/esm/flashcard/flashcard.d.ts.map +1 -1
  52. package/dist/esm/hack/hack.d.ts +3 -0
  53. package/dist/esm/hack/hack.d.ts.map +1 -1
  54. package/dist/esm/hack-mapping/app-hack-metadata.d.ts.map +1 -1
  55. package/dist/esm/hack-mapping/app-hack-metadata.js +1 -0
  56. package/dist/esm/hack-mapping/app-hack-metadata.js.map +1 -1
  57. package/dist/esm/identity-provider/identity-provider.d.ts +0 -4
  58. package/dist/esm/identity-provider/identity-provider.d.ts.map +1 -1
  59. package/dist/esm/index.d.ts +2 -0
  60. package/dist/esm/index.d.ts.map +1 -1
  61. package/dist/esm/index.js +2 -0
  62. package/dist/esm/index.js.map +1 -1
  63. package/dist/esm/interest/interest.d.ts +1 -0
  64. package/dist/esm/interest/interest.d.ts.map +1 -1
  65. package/dist/esm/knowledge-source/knowledge-source.d.ts +2 -0
  66. package/dist/esm/knowledge-source/knowledge-source.d.ts.map +1 -1
  67. package/dist/esm/pending-hack/pending-hack.d.ts +2 -0
  68. package/dist/esm/pending-hack/pending-hack.d.ts.map +1 -1
  69. package/dist/esm/spark/spark.d.ts +1 -1
  70. package/dist/esm/spark/spark.d.ts.map +1 -1
  71. package/dist/esm/topics/primary-topic-mapping.d.ts +11 -0
  72. package/dist/esm/topics/primary-topic-mapping.d.ts.map +1 -0
  73. package/dist/esm/topics/primary-topic-mapping.js +114 -0
  74. package/dist/esm/topics/primary-topic-mapping.js.map +1 -0
  75. package/dist/esm/topics/primary-topic.d.ts +4 -0
  76. package/dist/esm/topics/primary-topic.d.ts.map +1 -0
  77. package/dist/esm/topics/primary-topic.js +2 -0
  78. package/dist/esm/topics/primary-topic.js.map +1 -0
  79. package/package.json +2 -2
  80. package/src/access-control/collection-access-control.ts +28 -28
  81. package/src/access-control/hack-access-control.ts +32 -32
  82. package/src/access-control/profile-access-control.ts +27 -27
  83. package/src/app-hack/app-full-hack.ts +9 -9
  84. package/src/app-hack/app-hack-metadata.ts +62 -61
  85. package/src/app-hack/app-restricted-hack.ts +22 -22
  86. package/src/b2b-content-access/b2b-content-access.ts +57 -57
  87. package/src/b2b-organisation/b2b-carousel.ts +33 -33
  88. package/src/b2b-organisation/b2b-org-idp-mapping.ts +27 -27
  89. package/src/b2b-organisation/b2b-organisation-events.ts +21 -21
  90. package/src/b2b-organisation/b2b-organisation-group-events.ts +21 -21
  91. package/src/b2b-organisation/b2b-organisation-group-membership-events.ts +21 -21
  92. package/src/b2b-organisation/b2b-organisation-group-membership.ts +17 -17
  93. package/src/b2b-organisation/b2b-organisation-group.ts +42 -42
  94. package/src/b2b-organisation/b2b-organisation-invitation.ts +45 -45
  95. package/src/b2b-organisation/b2b-organisation-member-events.ts +21 -21
  96. package/src/b2b-organisation/b2b-organisation-member.ts +19 -19
  97. package/src/b2b-organisation/b2b-organisation.ts +38 -38
  98. package/src/brand/brand-events.ts +21 -21
  99. package/src/brand/brand.ts +77 -77
  100. package/src/catalogue/catalogue.ts +152 -152
  101. package/src/cms-hack/cms-searchable-hack.ts +47 -44
  102. package/src/collection/collection-events.ts +21 -21
  103. package/src/collection/collection.ts +59 -59
  104. package/src/collection/enriched-collection-events.ts +18 -18
  105. package/src/collection/enriched-collection.ts +65 -65
  106. package/src/course/course-events.ts +20 -20
  107. package/src/course/course.ts +25 -25
  108. package/src/course-enrollment/course-enrollment-events.ts +21 -21
  109. package/src/course-enrollment/course-enrollment.ts +36 -36
  110. package/src/creator/creator-events.ts +32 -32
  111. package/src/creator/creator.ts +7 -7
  112. package/src/distribution/collection-distribution.ts +17 -17
  113. package/src/distribution/distribution-events.ts +61 -61
  114. package/src/distribution/hack-distribution.ts +18 -18
  115. package/src/draft-hack/draft-hack-events.ts +21 -21
  116. package/src/draft-hack/draft-hack.ts +192 -190
  117. package/src/draft-hack-generation/draft-hack-generation-commands.ts +10 -10
  118. package/src/draft-hack-generation/draft-hack-generation-events.ts +52 -52
  119. package/src/draft-hack-generation/draft-hack-generation.ts +42 -39
  120. package/src/enriched-b2b-organisation/enriched-b2b-organisation-events.ts +21 -21
  121. package/src/enriched-b2b-organisation/enriched-b2b-organisation.ts +37 -37
  122. package/src/enriched-hack/enriched-hack-events.ts +21 -21
  123. package/src/enriched-hack/enriched-hack.ts +111 -109
  124. package/src/enrichment-asset/hack-enrichment-video-events.ts +55 -55
  125. package/src/enrichment-asset/hack-enrichment-video.ts +40 -40
  126. package/src/entitlement/user-entitlements-commands.ts +54 -54
  127. package/src/entitlement/user-entitlements-events.ts +29 -29
  128. package/src/entitlement/user-entitlements.ts +18 -18
  129. package/src/flashcard/flashcard-events.ts +85 -85
  130. package/src/flashcard/flashcard.ts +161 -138
  131. package/src/hack/extracted-subject.ts +31 -31
  132. package/src/hack/hack-events.ts +21 -21
  133. package/src/hack/hack-published.ts +21 -21
  134. package/src/hack/hack-with-voice-events.ts +20 -20
  135. package/src/hack/hack-with-voice.ts +36 -36
  136. package/src/hack/hack.ts +130 -127
  137. package/src/hack/publish-hack-command.ts +20 -20
  138. package/src/hack/republish-hack-command.ts +20 -20
  139. package/src/hack-mapping/access-helper.ts +6 -6
  140. package/src/hack-mapping/app-full-hack.test.ts +13 -13
  141. package/src/hack-mapping/app-full-hack.ts +14 -14
  142. package/src/hack-mapping/app-hack-metadata.test.ts +22 -22
  143. package/src/hack-mapping/app-hack-metadata.ts +83 -82
  144. package/src/hack-mapping/app-restricted-hack.test.ts +12 -12
  145. package/src/hack-mapping/app-restricted-hack.ts +21 -21
  146. package/src/hack-mapping/remove-undefined-fields.ts +9 -9
  147. package/src/hack-mapping/test-data/enriched-hack.json +2569 -2564
  148. package/src/hack-mapping/test-data/expected-app-full-hack.json +2502 -2497
  149. package/src/hack-mapping/test-data/expected-app-hack-metadata.json +86 -81
  150. package/src/hack-mapping/test-data/expected-app-restricted-hack.json +792 -787
  151. package/src/hack-metadata/hack-metadata-events.ts +21 -21
  152. package/src/hack-metadata/hack-metadata.ts +17 -17
  153. package/src/hack-of-the-day/hack-of-the-day-events.ts +21 -21
  154. package/src/hack-of-the-day/hack-of-the-day.ts +13 -13
  155. package/src/hack-statistics/hack-statistics-events.ts +21 -21
  156. package/src/hack-statistics/hack-statistics.ts +9 -9
  157. package/src/hackbot/hack-generation-commands.ts +45 -45
  158. package/src/hackbot/hack-generation-trigger-events.ts +21 -21
  159. package/src/hackbot/hack-generation-trigger.ts +57 -57
  160. package/src/history/history-events.ts +21 -21
  161. package/src/history/history.ts +46 -46
  162. package/src/identity-provider/domain-identity-provider-events.ts +20 -20
  163. package/src/identity-provider/domain-identity-provider.ts +10 -10
  164. package/src/identity-provider/identity-provider-events.ts +20 -20
  165. package/src/identity-provider/identity-provider.ts +47 -51
  166. package/src/index.ts +223 -220
  167. package/src/interest/interest-events.ts +21 -21
  168. package/src/interest/interest.ts +16 -15
  169. package/src/knowledge-source/knowledge-source-events.ts +21 -21
  170. package/src/knowledge-source/knowledge-source.ts +46 -43
  171. package/src/knowledge-source-parsing/knowledge-source-metadata.ts +58 -58
  172. package/src/knowledge-source-parsing/knowledge-source-parsing-commands.ts +41 -41
  173. package/src/knowledge-source-parsing/knowledge-source-parsing-events.ts +30 -30
  174. package/src/knowledge-source-parsing/podcast-metadata.ts +44 -44
  175. package/src/knowledge-source-parsing/podcast-parsing-events.ts +28 -28
  176. package/src/knowledge-source-parsing/user-hack-generation-options.ts +7 -7
  177. package/src/learn-upon/get-sqsso-url.ts +13 -13
  178. package/src/learn-upon/learn-upon-commands.ts +33 -33
  179. package/src/learn-upon/learn-upon-course-enrollment-events.ts +21 -21
  180. package/src/learn-upon/learn-upon-course-enrollment.ts +62 -62
  181. package/src/learn-upon/learn-upon-course-events.ts +21 -21
  182. package/src/learn-upon/learn-upon-course.ts +108 -108
  183. package/src/learn-upon/learn-upon-portal-events.ts +20 -20
  184. package/src/learn-upon/learn-upon-portal.ts +12 -12
  185. package/src/learn-upon/learn-upon-user-mapping-events.ts +18 -18
  186. package/src/learn-upon/learn-upon-user-mapping.ts +9 -9
  187. package/src/learn-upon/learn-upon-webhook-events.ts +80 -80
  188. package/src/learn-upon/learn-upon-webhook-types.ts +346 -346
  189. package/src/learn-upon/unenroll.ts +6 -6
  190. package/src/localisation/live-locales.ts +45 -45
  191. package/src/localisation/locale-language.ts +4 -4
  192. package/src/localisation/supported-languages.ts +11 -11
  193. package/src/localisation/supported-locales.ts +67 -67
  194. package/src/message-bus/context.ts +7 -7
  195. package/src/moderation/hack-moderation-result-events.ts +18 -18
  196. package/src/moderation/hack-moderation-result.ts +27 -27
  197. package/src/partner/partner-events.ts +21 -21
  198. package/src/partner/partner.ts +7 -7
  199. package/src/pending-hack/pending-hack-events.ts +20 -20
  200. package/src/pending-hack/pending-hack-with-voice-events.ts +20 -20
  201. package/src/pending-hack/pending-hack-with-voice.ts +25 -25
  202. package/src/pending-hack/pending-hack.ts +80 -78
  203. package/src/preferences/preferences-events.ts +15 -15
  204. package/src/preferences/preferences.ts +35 -35
  205. package/src/profile/profile-events.ts +41 -41
  206. package/src/profile/profile.ts +36 -36
  207. package/src/profile/translated-profile.ts +13 -13
  208. package/src/referral/referral-events.ts +41 -41
  209. package/src/referral/referral.ts +76 -76
  210. package/src/saved/saved-collection-events.ts +19 -19
  211. package/src/saved/saved-collection.ts +8 -8
  212. package/src/segment/segment-commands.ts +75 -75
  213. package/src/segment/segment-events.ts +42 -42
  214. package/src/segment/segment-with-voice.ts +8 -8
  215. package/src/segment/segment.ts +82 -82
  216. package/src/service-simulator/mock-request-response.ts +17 -17
  217. package/src/skin/skin-events.ts +21 -21
  218. package/src/skin/skin.ts +6 -6
  219. package/src/spark/spark-board-read-model.ts +17 -17
  220. package/src/spark/spark-board.ts +12 -12
  221. package/src/spark/spark-events.ts +42 -42
  222. package/src/spark/spark.ts +74 -75
  223. package/src/text-analysis/hack-categories-extracted-events.ts +24 -24
  224. package/src/text-analysis/hack-categories-extracted.ts +31 -31
  225. package/src/text-analysis/hack-entities-extracted-events.ts +24 -24
  226. package/src/text-analysis/hack-entities-extracted.ts +38 -38
  227. package/src/text-analysis/hack-keywords-extracted-events.ts +24 -24
  228. package/src/text-analysis/hack-keywords-extracted.ts +23 -23
  229. package/src/text-analysis/hack-topics-extracted-events.ts +24 -24
  230. package/src/text-analysis/hack-topics-extracted.ts +31 -31
  231. package/src/text-to-speech/create-speech-commands.ts +22 -22
  232. package/src/text-to-speech/speech-created-events.ts +10 -10
  233. package/src/text-to-speech/supported-voices.ts +222 -222
  234. package/src/text-to-speech/text-segment.ts +29 -29
  235. package/src/theme/theme-events.ts +21 -21
  236. package/src/theme/theme.ts +68 -68
  237. package/src/topics/primary-topic-mapping.test.ts +87 -0
  238. package/src/topics/primary-topic-mapping.ts +136 -0
  239. package/src/topics/primary-topic.ts +3 -0
  240. package/src/translation/translation-events.ts +73 -73
  241. package/src/translation/translation.ts +25 -25
  242. package/src/trending/trending-events.ts +21 -21
  243. package/src/trending/trending-hacks.ts +8 -8
  244. package/src/user/cognito-user-authentication-log.ts +7 -7
  245. package/src/user/get-user.ts +63 -63
  246. package/src/user/user-events.ts +39 -39
  247. package/src/user-acl/user-acl-utils.test.ts +273 -273
  248. package/src/user-acl/user-acl-utils.ts +176 -176
  249. package/src/user-context/user-context-events.ts +21 -21
  250. package/src/user-context/user-context.ts +15 -15
  251. package/src/user-notification-context/user-notification-context-events.ts +21 -21
  252. package/src/user-notification-context/user-notification-context.ts +9 -9
  253. package/src/user-statistics/user-statistics-events.ts +97 -97
  254. package/src/user-statistics/user-statistics.ts +82 -82
  255. package/src/video-cropping/video-cropping-events.ts +43 -43
  256. package/src/video-cropping/video-metadata.ts +12 -12
  257. package/tsconfig.cjs.json +7 -7
  258. package/tsconfig.npm.json +22 -22
@@ -1,177 +1,177 @@
1
- export type AclQueryMode = 'included' | 'excluded' | 'all';
2
-
3
- export interface ParsedAclEntry {
4
- raw: string;
5
- excluded: boolean;
6
- namespace: string;
7
- value: string | null;
8
- }
9
-
10
- export interface GetAclValuesOptions {
11
- mode?: AclQueryMode;
12
- dedupe?: boolean;
13
- }
14
-
15
- export interface BuildAclOptions {
16
- baseAcl?: string[];
17
- }
18
-
19
- function normalizeAclEntry(entry: string): string {
20
- return entry.trim();
21
- }
22
-
23
- export function parseAclEntry(entry: string): ParsedAclEntry | null {
24
- const raw = normalizeAclEntry(entry);
25
- if (!raw) {
26
- return null;
27
- }
28
-
29
- const excluded = raw.startsWith('!');
30
- const token = excluded ? raw.slice(1) : raw;
31
- const firstColonIndex = token.indexOf(':');
32
-
33
- if (firstColonIndex === -1) {
34
- return {
35
- raw,
36
- excluded,
37
- namespace: token,
38
- value: null
39
- };
40
- }
41
-
42
- const namespace = token.slice(0, firstColonIndex);
43
- const value = token.slice(firstColonIndex + 1);
44
-
45
- if (!namespace) {
46
- return null;
47
- }
48
-
49
- return {
50
- raw,
51
- excluded,
52
- namespace,
53
- value
54
- };
55
- }
56
-
57
- export function getAclValuesByNamespace(
58
- acl: string[],
59
- namespace: string,
60
- options: GetAclValuesOptions = {}
61
- ): string[] {
62
- const mode = options.mode ?? 'included';
63
- const dedupe = options.dedupe ?? true;
64
-
65
- const values = acl
66
- .map(parseAclEntry)
67
- .filter((entry): entry is ParsedAclEntry => Boolean(entry))
68
- .filter(entry => entry.namespace === namespace)
69
- .filter(entry => entry.value !== null)
70
- .filter(entry => {
71
- if (mode === 'all') {
72
- return true;
73
- }
74
- if (mode === 'included') {
75
- return !entry.excluded;
76
- }
77
- return entry.excluded;
78
- })
79
- .map(entry => entry.value as string);
80
-
81
- return dedupe ? Array.from(new Set(values)) : values;
82
- }
83
-
84
- export function aclFor({ userId, organisationIds, catalogueIds }: { userId: string; organisationIds: string[]; catalogueIds: string[] }) {
85
- const builder = new UserAclBuilder()
86
- .allowPublic()
87
- .allowUser(userId);
88
-
89
- // everyone has access to the uptime catalogue
90
- builder.allowCatalogue('uptime');
91
-
92
- catalogueIds.forEach(catalogueId => builder.allowCatalogue(catalogueId));
93
-
94
- // each b2b has a catalogue called b2b:<organisationId> so permit access to this
95
- organisationIds.forEach(organisationId => builder.allowCatalogue(`b2b:${organisationId}`));
96
-
97
- // previously we also had acl of b2b:<organisationId> that is still being used for collections
98
- organisationIds.forEach(organisationId => builder.allowOrganisation(organisationId));
99
-
100
- return builder.build();
101
- }
102
-
103
- export class UserAclBuilder {
104
- private included = new Set<string>();
105
- private excluded = new Set<string>();
106
-
107
- constructor(options: BuildAclOptions = {}) {
108
- if (options.baseAcl?.length) {
109
- this.addMany(options.baseAcl);
110
- }
111
- }
112
-
113
- addRaw(entry: string): this {
114
- const parsed = parseAclEntry(entry);
115
- if (!parsed) {
116
- return this;
117
- }
118
-
119
- if (parsed.excluded) {
120
- this.excluded.add(parsed.raw.slice(1));
121
- } else {
122
- this.included.add(parsed.raw);
123
- }
124
-
125
- return this;
126
- }
127
-
128
- addMany(entries: string[]): this {
129
- entries.forEach(entry => this.addRaw(entry));
130
- return this;
131
- }
132
-
133
- allow(namespace: string, value?: string): this {
134
- const token = value === undefined ? namespace : `${namespace}:${value}`;
135
- this.included.add(token);
136
- this.excluded.delete(token);
137
- return this;
138
- }
139
-
140
- deny(namespace: string, value?: string): this {
141
- const token = value === undefined ? namespace : `${namespace}:${value}`;
142
- this.excluded.add(token);
143
- this.included.delete(token);
144
- return this;
145
- }
146
-
147
- allowCatalogue(catalogueId: string): this {
148
- return this.allow('catalogue', catalogueId);
149
- }
150
-
151
- allowPublic(): this {
152
- return this.allow('public');
153
- }
154
-
155
- allowUser(userId: string): this {
156
- return this.allow('user', userId);
157
- }
158
-
159
- denyCatalogue(catalogueId: string): this {
160
- return this.deny('catalogue', catalogueId);
161
- }
162
-
163
- allowOrganisation(organisationId: string): this {
164
- return this.allow('b2b', organisationId);
165
- }
166
-
167
- denySubject(subject: string): this {
168
- return this.deny('subject', subject);
169
- }
170
-
171
- build(): string[] {
172
- return [
173
- ...this.included,
174
- ...Array.from(this.excluded).map(token => `!${token}`)
175
- ];
176
- }
1
+ export type AclQueryMode = 'included' | 'excluded' | 'all';
2
+
3
+ export interface ParsedAclEntry {
4
+ raw: string;
5
+ excluded: boolean;
6
+ namespace: string;
7
+ value: string | null;
8
+ }
9
+
10
+ export interface GetAclValuesOptions {
11
+ mode?: AclQueryMode;
12
+ dedupe?: boolean;
13
+ }
14
+
15
+ export interface BuildAclOptions {
16
+ baseAcl?: string[];
17
+ }
18
+
19
+ function normalizeAclEntry(entry: string): string {
20
+ return entry.trim();
21
+ }
22
+
23
+ export function parseAclEntry(entry: string): ParsedAclEntry | null {
24
+ const raw = normalizeAclEntry(entry);
25
+ if (!raw) {
26
+ return null;
27
+ }
28
+
29
+ const excluded = raw.startsWith('!');
30
+ const token = excluded ? raw.slice(1) : raw;
31
+ const firstColonIndex = token.indexOf(':');
32
+
33
+ if (firstColonIndex === -1) {
34
+ return {
35
+ raw,
36
+ excluded,
37
+ namespace: token,
38
+ value: null
39
+ };
40
+ }
41
+
42
+ const namespace = token.slice(0, firstColonIndex);
43
+ const value = token.slice(firstColonIndex + 1);
44
+
45
+ if (!namespace) {
46
+ return null;
47
+ }
48
+
49
+ return {
50
+ raw,
51
+ excluded,
52
+ namespace,
53
+ value
54
+ };
55
+ }
56
+
57
+ export function getAclValuesByNamespace(
58
+ acl: string[],
59
+ namespace: string,
60
+ options: GetAclValuesOptions = {}
61
+ ): string[] {
62
+ const mode = options.mode ?? 'included';
63
+ const dedupe = options.dedupe ?? true;
64
+
65
+ const values = acl
66
+ .map(parseAclEntry)
67
+ .filter((entry): entry is ParsedAclEntry => Boolean(entry))
68
+ .filter(entry => entry.namespace === namespace)
69
+ .filter(entry => entry.value !== null)
70
+ .filter(entry => {
71
+ if (mode === 'all') {
72
+ return true;
73
+ }
74
+ if (mode === 'included') {
75
+ return !entry.excluded;
76
+ }
77
+ return entry.excluded;
78
+ })
79
+ .map(entry => entry.value as string);
80
+
81
+ return dedupe ? Array.from(new Set(values)) : values;
82
+ }
83
+
84
+ export function aclFor({ userId, organisationIds, catalogueIds }: { userId: string; organisationIds: string[]; catalogueIds: string[] }) {
85
+ const builder = new UserAclBuilder()
86
+ .allowPublic()
87
+ .allowUser(userId);
88
+
89
+ // everyone has access to the uptime catalogue
90
+ builder.allowCatalogue('uptime');
91
+
92
+ catalogueIds.forEach(catalogueId => builder.allowCatalogue(catalogueId));
93
+
94
+ // each b2b has a catalogue called b2b:<organisationId> so permit access to this
95
+ organisationIds.forEach(organisationId => builder.allowCatalogue(`b2b:${organisationId}`));
96
+
97
+ // previously we also had acl of b2b:<organisationId> that is still being used for collections
98
+ organisationIds.forEach(organisationId => builder.allowOrganisation(organisationId));
99
+
100
+ return builder.build();
101
+ }
102
+
103
+ export class UserAclBuilder {
104
+ private included = new Set<string>();
105
+ private excluded = new Set<string>();
106
+
107
+ constructor(options: BuildAclOptions = {}) {
108
+ if (options.baseAcl?.length) {
109
+ this.addMany(options.baseAcl);
110
+ }
111
+ }
112
+
113
+ addRaw(entry: string): this {
114
+ const parsed = parseAclEntry(entry);
115
+ if (!parsed) {
116
+ return this;
117
+ }
118
+
119
+ if (parsed.excluded) {
120
+ this.excluded.add(parsed.raw.slice(1));
121
+ } else {
122
+ this.included.add(parsed.raw);
123
+ }
124
+
125
+ return this;
126
+ }
127
+
128
+ addMany(entries: string[]): this {
129
+ entries.forEach(entry => this.addRaw(entry));
130
+ return this;
131
+ }
132
+
133
+ allow(namespace: string, value?: string): this {
134
+ const token = value === undefined ? namespace : `${namespace}:${value}`;
135
+ this.included.add(token);
136
+ this.excluded.delete(token);
137
+ return this;
138
+ }
139
+
140
+ deny(namespace: string, value?: string): this {
141
+ const token = value === undefined ? namespace : `${namespace}:${value}`;
142
+ this.excluded.add(token);
143
+ this.included.delete(token);
144
+ return this;
145
+ }
146
+
147
+ allowCatalogue(catalogueId: string): this {
148
+ return this.allow('catalogue', catalogueId);
149
+ }
150
+
151
+ allowPublic(): this {
152
+ return this.allow('public');
153
+ }
154
+
155
+ allowUser(userId: string): this {
156
+ return this.allow('user', userId);
157
+ }
158
+
159
+ denyCatalogue(catalogueId: string): this {
160
+ return this.deny('catalogue', catalogueId);
161
+ }
162
+
163
+ allowOrganisation(organisationId: string): this {
164
+ return this.allow('b2b', organisationId);
165
+ }
166
+
167
+ denySubject(subject: string): this {
168
+ return this.deny('subject', subject);
169
+ }
170
+
171
+ build(): string[] {
172
+ return [
173
+ ...this.included,
174
+ ...Array.from(this.excluded).map(token => `!${token}`)
175
+ ];
176
+ }
177
177
  }
@@ -1,21 +1,21 @@
1
- import { UserContext } from './user-context';
2
-
3
- export interface UserContextCreatedEvent {
4
- id: string;
5
- type: 'UserContextCreated';
6
- payload: UserContext;
7
- }
8
-
9
- export interface UserContextUpdatedEvent {
10
- id: string;
11
- type: 'UserContextUpdated';
12
- payload: UserContext;
13
- }
14
-
15
- export interface UserContextDeletedEvent {
16
- id: string;
17
- type: 'UserContextDeleted';
18
- payload: UserContext;
19
- }
20
-
21
- export type UserContextChangedEvent = UserContextCreatedEvent | UserContextUpdatedEvent | UserContextDeletedEvent;
1
+ import { UserContext } from './user-context';
2
+
3
+ export interface UserContextCreatedEvent {
4
+ id: string;
5
+ type: 'UserContextCreated';
6
+ payload: UserContext;
7
+ }
8
+
9
+ export interface UserContextUpdatedEvent {
10
+ id: string;
11
+ type: 'UserContextUpdated';
12
+ payload: UserContext;
13
+ }
14
+
15
+ export interface UserContextDeletedEvent {
16
+ id: string;
17
+ type: 'UserContextDeleted';
18
+ payload: UserContext;
19
+ }
20
+
21
+ export type UserContextChangedEvent = UserContextCreatedEvent | UserContextUpdatedEvent | UserContextDeletedEvent;
@@ -1,16 +1,16 @@
1
- import { Entitlement } from '../entitlement/user-entitlements';
2
-
3
- export interface UserContext {
4
- id: string;
5
- v: number;
6
- createdAt: string;
7
- updatedAt: string;
8
- userId: string;
9
- entitlements: Entitlement[];
10
- organisationIds: string[];
11
- roles: string[];
12
- acl: string[];
13
- partnerId?: string;
14
- brandId?: string;
15
- skinId?: string;
1
+ import { Entitlement } from '../entitlement/user-entitlements';
2
+
3
+ export interface UserContext {
4
+ id: string;
5
+ v: number;
6
+ createdAt: string;
7
+ updatedAt: string;
8
+ userId: string;
9
+ entitlements: Entitlement[];
10
+ organisationIds: string[];
11
+ roles: string[];
12
+ acl: string[];
13
+ partnerId?: string;
14
+ brandId?: string;
15
+ skinId?: string;
16
16
  }
@@ -1,21 +1,21 @@
1
- import { UserNotificationContext } from './user-notification-context';
2
-
3
- export interface UserNotificationContextCreatedEvent {
4
- id: string;
5
- type: 'UserNotificationContextCreated';
6
- payload: UserNotificationContext;
7
- }
8
-
9
- export interface UserNotificationContextUpdatedEvent {
10
- id: string;
11
- type: 'UserNotificationContextUpdated';
12
- payload: UserNotificationContext;
13
- }
14
-
15
- export interface UserNotificationContextDeletedEvent {
16
- id: string;
17
- type: 'UserNotificationContextDeleted';
18
- payload: UserNotificationContext;
19
- }
20
-
21
- export type UserNotificationContextChangedEvent = UserNotificationContextCreatedEvent | UserNotificationContextUpdatedEvent | UserNotificationContextDeletedEvent;
1
+ import { UserNotificationContext } from './user-notification-context';
2
+
3
+ export interface UserNotificationContextCreatedEvent {
4
+ id: string;
5
+ type: 'UserNotificationContextCreated';
6
+ payload: UserNotificationContext;
7
+ }
8
+
9
+ export interface UserNotificationContextUpdatedEvent {
10
+ id: string;
11
+ type: 'UserNotificationContextUpdated';
12
+ payload: UserNotificationContext;
13
+ }
14
+
15
+ export interface UserNotificationContextDeletedEvent {
16
+ id: string;
17
+ type: 'UserNotificationContextDeleted';
18
+ payload: UserNotificationContext;
19
+ }
20
+
21
+ export type UserNotificationContextChangedEvent = UserNotificationContextCreatedEvent | UserNotificationContextUpdatedEvent | UserNotificationContextDeletedEvent;
@@ -1,10 +1,10 @@
1
- export interface UserNotificationContext {
2
- id: string;
3
- userId: string;
4
- v: number;
5
- createdAt: string;
6
- updatedAt: string;
7
- skinId: string;
8
- brandId?: string;
9
- translationVariation: string;
1
+ export interface UserNotificationContext {
2
+ id: string;
3
+ userId: string;
4
+ v: number;
5
+ createdAt: string;
6
+ updatedAt: string;
7
+ skinId: string;
8
+ brandId?: string;
9
+ translationVariation: string;
10
10
  }