Skip to content

Commit 9250ab7

Browse files
committed
Merge branch 'feature/offline-pdfs' into develop
2 parents db530a1 + 8ce337a commit 9250ab7

File tree

9 files changed

+265
-51
lines changed

9 files changed

+265
-51
lines changed

firebase/firestore.rules

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,72 @@ service cloud.firestore {
8787
request.auth.uid == resource.data.user
8888
;
8989
}
90+
match /personalAnalyticEvent/{user} {
91+
match /objects/{personalAnalyticEvent} {
92+
allow create: if
93+
// Type checks
94+
request.resource.data.createdWhen is timestamp &&
95+
request.resource.data.type is string &&
96+
(!('str1' in request.resource.data.keys()) || request.resource.data.str1 == null || request.resource.data.str1 is string) &&
97+
(!('str2' in request.resource.data.keys()) || request.resource.data.str2 == null || request.resource.data.str2 is string) &&
98+
(!('str3' in request.resource.data.keys()) || request.resource.data.str3 == null || request.resource.data.str3 is string) &&
99+
(!('float1' in request.resource.data.keys()) || request.resource.data.float1 == null || request.resource.data.float1 is number) &&
100+
(!('float2' in request.resource.data.keys()) || request.resource.data.float2 == null || request.resource.data.float2 is number) &&
101+
(!('float3' in request.resource.data.keys()) || request.resource.data.float3 == null || request.resource.data.float3 is number) &&
102+
(!('time1' in request.resource.data.keys()) || request.resource.data.time1 == null || request.resource.data.time1 is timestamp) &&
103+
(!('time2' in request.resource.data.keys()) || request.resource.data.time2 == null || request.resource.data.time2 is timestamp) &&
104+
(!('time3' in request.resource.data.keys()) || request.resource.data.time3 == null || request.resource.data.time3 is timestamp) &&
105+
106+
107+
// Ownership rules
108+
request.auth.uid == user
109+
;
110+
allow update: if
111+
// Type checks
112+
(!('createdWhen' in request.resource.data.keys()) || request.resource.data.createdWhen is timestamp) &&
113+
(!('type' in request.resource.data.keys()) || request.resource.data.type is string) &&
114+
(!('str1' in request.resource.data.keys()) || request.resource.data.str1 == null || request.resource.data.str1 is string) &&
115+
(!('str2' in request.resource.data.keys()) || request.resource.data.str2 == null || request.resource.data.str2 is string) &&
116+
(!('str3' in request.resource.data.keys()) || request.resource.data.str3 == null || request.resource.data.str3 is string) &&
117+
(!('float1' in request.resource.data.keys()) || request.resource.data.float1 == null || request.resource.data.float1 is number) &&
118+
(!('float2' in request.resource.data.keys()) || request.resource.data.float2 == null || request.resource.data.float2 is number) &&
119+
(!('float3' in request.resource.data.keys()) || request.resource.data.float3 == null || request.resource.data.float3 is number) &&
120+
(!('time1' in request.resource.data.keys()) || request.resource.data.time1 == null || request.resource.data.time1 is timestamp) &&
121+
(!('time2' in request.resource.data.keys()) || request.resource.data.time2 == null || request.resource.data.time2 is timestamp) &&
122+
(!('time3' in request.resource.data.keys()) || request.resource.data.time3 == null || request.resource.data.time3 is timestamp) &&
123+
124+
125+
// Ownership rules
126+
request.auth.uid == user
127+
;
128+
}
129+
}
130+
match /personalAnalyticStats/{user} {
131+
allow get: if
132+
// Ownership rules
133+
request.auth.uid == user
134+
;
135+
allow create: if
136+
// Type checks
137+
request.resource.data.installedWhen is timestamp &&
138+
(!('registeredWhen' in request.resource.data.keys()) || request.resource.data.registeredWhen == null || request.resource.data.registeredWhen is timestamp) &&
139+
(!('uninstalledWhen' in request.resource.data.keys()) || request.resource.data.uninstalledWhen == null || request.resource.data.uninstalledWhen is timestamp) &&
140+
141+
142+
// Ownership rules
143+
request.auth.uid == user
144+
;
145+
allow update: if
146+
// Type checks
147+
(!('installedWhen' in request.resource.data.keys()) || request.resource.data.installedWhen is timestamp) &&
148+
(!('registeredWhen' in request.resource.data.keys()) || request.resource.data.registeredWhen == null || request.resource.data.registeredWhen is timestamp) &&
149+
(!('uninstalledWhen' in request.resource.data.keys()) || request.resource.data.uninstalledWhen == null || request.resource.data.uninstalledWhen is timestamp) &&
150+
151+
152+
// Ownership rules
153+
request.auth.uid == user
154+
;
155+
}
90156
match /sharedList/{sharedList} {
91157
allow get: if
92158
// Permission rules
@@ -147,6 +213,64 @@ service cloud.firestore {
147213
;
148214
}
149215
}
216+
match /sharedContentFingerprint/{sharedContentFingerprint} {
217+
allow get: if
218+
// Permission rules
219+
true
220+
;
221+
allow create: if
222+
// Type checks
223+
request.resource.data.normalizedUrl is string &&
224+
request.resource.data.fingerprintScheme is string &&
225+
request.resource.data.fingerprint is string &&
226+
227+
228+
// Permission rules
229+
(request.auth.uid == request.resource.data.creator && ((get(/databases/$(database)/documents/sharedList/$(request.resource.data.sharedList)).data.creator == request.resource.data.creator) || (exists(/databases/$(database)/documents/sharedListRole/$(request.resource.data.sharedList)/users/$(request.auth.uid)) && (get(/databases/$(database)/documents/sharedListRole/$(request.resource.data.sharedList)/users/$(request.auth.uid)).data.roleID >= 400))))
230+
;
231+
allow update: if
232+
// Type checks
233+
(!('normalizedUrl' in request.resource.data.keys()) || request.resource.data.normalizedUrl is string) &&
234+
(!('fingerprintScheme' in request.resource.data.keys()) || request.resource.data.fingerprintScheme is string) &&
235+
(!('fingerprint' in request.resource.data.keys()) || request.resource.data.fingerprint is string) &&
236+
237+
238+
// Permission rules
239+
(request.auth.uid == resource.data.creator && ((!('creator' in request.resource.data.keys())) || request.auth.uid == request.resource.data.creator) && ((get(/databases/$(database)/documents/sharedList/$(request.resource.data.sharedList)).data.creator == request.resource.data.creator) || (exists(/databases/$(database)/documents/sharedListRole/$(request.resource.data.sharedList)/users/$(request.auth.uid)) && (get(/databases/$(database)/documents/sharedListRole/$(request.resource.data.sharedList)/users/$(request.auth.uid)).data.roleID >= 400))))
240+
;
241+
allow delete: if
242+
// Permission rules
243+
(request.auth.uid == resource.data.creator && ((get(/databases/$(database)/documents/sharedList/$(resource.data.sharedList)).data.creator == resource.data.creator) || (exists(/databases/$(database)/documents/sharedListRole/$(resource.data.sharedList)/users/$(request.auth.uid)) && (get(/databases/$(database)/documents/sharedListRole/$(resource.data.sharedList)/users/$(request.auth.uid)).data.roleID >= 400))))
244+
;
245+
}
246+
match /sharedContentLocator/{sharedContentLocator} {
247+
allow get: if
248+
// Permission rules
249+
true
250+
;
251+
allow create: if
252+
// Type checks
253+
request.resource.data.normalizedUrl is string &&
254+
request.resource.data.originalUrl is string &&
255+
256+
257+
// Permission rules
258+
(request.auth.uid == request.resource.data.creator && ((get(/databases/$(database)/documents/sharedList/$(request.resource.data.sharedList)).data.creator == request.resource.data.creator) || (exists(/databases/$(database)/documents/sharedListRole/$(request.resource.data.sharedList)/users/$(request.auth.uid)) && (get(/databases/$(database)/documents/sharedListRole/$(request.resource.data.sharedList)/users/$(request.auth.uid)).data.roleID >= 400))))
259+
;
260+
allow update: if
261+
// Type checks
262+
(!('normalizedUrl' in request.resource.data.keys()) || request.resource.data.normalizedUrl is string) &&
263+
(!('originalUrl' in request.resource.data.keys()) || request.resource.data.originalUrl is string) &&
264+
265+
266+
// Permission rules
267+
(request.auth.uid == resource.data.creator && ((!('creator' in request.resource.data.keys())) || request.auth.uid == request.resource.data.creator) && ((get(/databases/$(database)/documents/sharedList/$(request.resource.data.sharedList)).data.creator == request.resource.data.creator) || (exists(/databases/$(database)/documents/sharedListRole/$(request.resource.data.sharedList)/users/$(request.auth.uid)) && (get(/databases/$(database)/documents/sharedListRole/$(request.resource.data.sharedList)/users/$(request.auth.uid)).data.roleID >= 400))))
268+
;
269+
allow delete: if
270+
// Permission rules
271+
(request.auth.uid == resource.data.creator && ((get(/databases/$(database)/documents/sharedList/$(resource.data.sharedList)).data.creator == resource.data.creator) || (exists(/databases/$(database)/documents/sharedListRole/$(resource.data.sharedList)/users/$(request.auth.uid)) && (get(/databases/$(database)/documents/sharedListRole/$(resource.data.sharedList)/users/$(request.auth.uid)).data.roleID >= 400))))
272+
;
273+
}
150274
match /sharedListEntry/{sharedListEntry} {
151275
allow get: if
152276
// Permission rules
@@ -980,6 +1104,8 @@ service cloud.firestore {
9801104
request.resource.data.primary is bool &&
9811105
request.resource.data.valid is bool &&
9821106
request.resource.data.version is timestamp &&
1107+
(!('localId' in request.resource.data.keys()) || request.resource.data.localId == null || request.resource.data.localId is string) &&
1108+
(!('fingerprintScheme' in request.resource.data.keys()) || request.resource.data.fingerprintScheme == null || request.resource.data.fingerprintScheme is string) &&
9831109
(!('fingerprint' in request.resource.data.keys()) || request.resource.data.fingerprint == null || request.resource.data.fingerprint is string) &&
9841110
(!('lastVisited' in request.resource.data.keys()) || request.resource.data.lastVisited == null || request.resource.data.lastVisited is timestamp) &&
9851111
(!('contentSize' in request.resource.data.keys()) || request.resource.data.contentSize == null || request.resource.data.contentSize is number) &&
@@ -1000,6 +1126,8 @@ service cloud.firestore {
10001126
(!('primary' in request.resource.data.keys()) || request.resource.data.primary is bool) &&
10011127
(!('valid' in request.resource.data.keys()) || request.resource.data.valid is bool) &&
10021128
(!('version' in request.resource.data.keys()) || request.resource.data.version is timestamp) &&
1129+
(!('localId' in request.resource.data.keys()) || request.resource.data.localId == null || request.resource.data.localId is string) &&
1130+
(!('fingerprintScheme' in request.resource.data.keys()) || request.resource.data.fingerprintScheme == null || request.resource.data.fingerprintScheme is string) &&
10031131
(!('fingerprint' in request.resource.data.keys()) || request.resource.data.fingerprint == null || request.resource.data.fingerprint is string) &&
10041132
(!('lastVisited' in request.resource.data.keys()) || request.resource.data.lastVisited == null || request.resource.data.lastVisited is timestamp) &&
10051133
(!('contentSize' in request.resource.data.keys()) || request.resource.data.contentSize == null || request.resource.data.contentSize is number) &&

firebase/functions/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"main": "lib/src/entry.js",
1818
"dependencies": {
1919
"@josephg/resolvable": "^1.0.0",
20-
"@sentry/node": "^6.13.3",
20+
"@sentry/node": "^6.15.0",
2121
"airtable": "^0.10.0",
2222
"axios": "^0.19.2",
2323
"bcrypt": "^3.0.6",

firebase/functions/yarn.lock

Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -631,72 +631,72 @@
631631
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
632632
integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=
633633

634-
"@sentry/core@6.13.3":
635-
version "6.13.3"
636-
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.13.3.tgz#5cbbb995128e793ebebcbf1d3b7514e0e5e8b221"
637-
integrity sha512-obm3SjgCk8A7nB37b2AU1eq1q7gMoJRrGMv9VRIyfcG0Wlz/5lJ9O3ohUk+YZaaVfZMxXn6hFtsBiOWmlv7IIA==
638-
dependencies:
639-
"@sentry/hub" "6.13.3"
640-
"@sentry/minimal" "6.13.3"
641-
"@sentry/types" "6.13.3"
642-
"@sentry/utils" "6.13.3"
634+
"@sentry/core@6.15.0":
635+
version "6.15.0"
636+
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.15.0.tgz#5e877042fe18452f2273247126b32e139d5f907c"
637+
integrity sha512-mCbKyqvD1G3Re6gv6N8tRkBz84gvVWDfLtC6d1WBArIopzter6ktEbvq0cMT6EOvGI2OLXuJ6mtHA93/Q0gGpw==
638+
dependencies:
639+
"@sentry/hub" "6.15.0"
640+
"@sentry/minimal" "6.15.0"
641+
"@sentry/types" "6.15.0"
642+
"@sentry/utils" "6.15.0"
643643
tslib "^1.9.3"
644644

645-
"@sentry/hub@6.13.3":
646-
version "6.13.3"
647-
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.13.3.tgz#cc09623a69b5343315fdb61c7fdd0be74b72299f"
648-
integrity sha512-eYppBVqvhs5cvm33snW2sxfcw6G20/74RbBn+E4WDo15hozis89kU7ZCJDOPkXuag3v1h9igns/kM6PNBb41dw==
645+
"@sentry/hub@6.15.0":
646+
version "6.15.0"
647+
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.15.0.tgz#fb8a91d12fdd2726a884374ea7242f6bbd081d69"
648+
integrity sha512-cUbHPeG6kKpGBaEMgbTWeU03Y1Up5T3urGF+cgtrn80PmPYYSUPvVvWlZQWPb8CJZ1yQ0gySWo5RUTatBFrEHA==
649649
dependencies:
650-
"@sentry/types" "6.13.3"
651-
"@sentry/utils" "6.13.3"
650+
"@sentry/types" "6.15.0"
651+
"@sentry/utils" "6.15.0"
652652
tslib "^1.9.3"
653653

654-
"@sentry/minimal@6.13.3":
655-
version "6.13.3"
656-
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.13.3.tgz#a675a79bcc830142e4f95e6198a2efde2cd3901e"
657-
integrity sha512-63MlYYRni3fs5Bh8XBAfVZ+ctDdWg0fapSTP1ydIC37fKvbE+5zhyUqwrEKBIiclEApg1VKX7bkKxVdu/vsFdw==
654+
"@sentry/minimal@6.15.0":
655+
version "6.15.0"
656+
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.15.0.tgz#fcc083ba901cfe57d25303d0b5fa8cd13e164466"
657+
integrity sha512-7RJIvZsjBa1qFUfMrAzQsWdfZT6Gm4t6ZTYfkpsXPBA35hkzglKbBrhhsUvkxGIhUGw/PiCUqxBUjcmzQP0vfg==
658658
dependencies:
659-
"@sentry/hub" "6.13.3"
660-
"@sentry/types" "6.13.3"
659+
"@sentry/hub" "6.15.0"
660+
"@sentry/types" "6.15.0"
661661
tslib "^1.9.3"
662662

663-
"@sentry/node@^6.13.3":
664-
version "6.13.3"
665-
resolved "https://registry.yarnpkg.com/@sentry/node/-/node-6.13.3.tgz#94c646c31fd240ab68ee8b85aa663e65eb499d06"
666-
integrity sha512-ZeZSw+TcPcf4e0j7iEqNMtoVmz+WFW/TEoGokXIwysZqSgchKdAXDHqn+CqUqFan7d76JcJmzztAUK2JruQ2Kg==
663+
"@sentry/node@^6.15.0":
664+
version "6.15.0"
665+
resolved "https://registry.yarnpkg.com/@sentry/node/-/node-6.15.0.tgz#d7b911e5667a3459a807a2ae0464558e872504d4"
666+
integrity sha512-V1GeupWi9ClmoMy5eBWdVTv3k+Yx/JpddT4zCzzYY9QfjYtEvQI7R3SWFtlgXuaQQaZNU0WUoE2UgJV2N/vS8g==
667667
dependencies:
668-
"@sentry/core" "6.13.3"
669-
"@sentry/hub" "6.13.3"
670-
"@sentry/tracing" "6.13.3"
671-
"@sentry/types" "6.13.3"
672-
"@sentry/utils" "6.13.3"
668+
"@sentry/core" "6.15.0"
669+
"@sentry/hub" "6.15.0"
670+
"@sentry/tracing" "6.15.0"
671+
"@sentry/types" "6.15.0"
672+
"@sentry/utils" "6.15.0"
673673
cookie "^0.4.1"
674674
https-proxy-agent "^5.0.0"
675675
lru_map "^0.3.3"
676676
tslib "^1.9.3"
677677

678-
"@sentry/tracing@6.13.3":
679-
version "6.13.3"
680-
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.13.3.tgz#ca657d4afa99c50f15e638fe38405bac33e780ee"
681-
integrity sha512-yyOFIhqlprPM0g4f35Icear3eZk2mwyYcGEzljJfY2iU6pJwj1lzia5PfSwiCW7jFGMmlBJNhOAIpfhlliZi8Q==
678+
"@sentry/tracing@6.15.0":
679+
version "6.15.0"
680+
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.15.0.tgz#5a5f08ee6b9cc1189227536fca053cd23488600d"
681+
integrity sha512-V5unvX8qNEfdawX+m2n0jKgmH/YR2ItWZLH+3UevBTptO+xyfvRtpgGXYWUCo3iGvFgWb1C+iIC7LViR9rTvBg==
682682
dependencies:
683-
"@sentry/hub" "6.13.3"
684-
"@sentry/minimal" "6.13.3"
685-
"@sentry/types" "6.13.3"
686-
"@sentry/utils" "6.13.3"
683+
"@sentry/hub" "6.15.0"
684+
"@sentry/minimal" "6.15.0"
685+
"@sentry/types" "6.15.0"
686+
"@sentry/utils" "6.15.0"
687687
tslib "^1.9.3"
688688

689-
"@sentry/types@6.13.3":
690-
version "6.13.3"
691-
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.13.3.tgz#63ad5b6735b0dfd90b3a256a9f8e77b93f0f66b2"
692-
integrity sha512-Vrz5CdhaTRSvCQjSyIFIaV9PodjAVFkzJkTRxyY7P77RcegMsRSsG1yzlvCtA99zG9+e6MfoJOgbOCwuZids5A==
689+
"@sentry/types@6.15.0":
690+
version "6.15.0"
691+
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.15.0.tgz#a2917f8aed91471bdfd6651384ffcd47b95c43ad"
692+
integrity sha512-zBw5gPUsofXUSpS3ZAXqRNedLRBvirl3sqkj2Lez7X2EkKRgn5D8m9fQIrig/X3TsKcXUpijDW5Buk5zeCVzJA==
693693

694-
"@sentry/utils@6.13.3":
695-
version "6.13.3"
696-
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.13.3.tgz#188754d40afe693c3fcae410f9322531588a9926"
697-
integrity sha512-zYFuFH3MaYtBZTeJ4Yajg7pDf0pM3MWs3+9k5my9Fd+eqNcl7dYQYJbT9gyC0HXK1QI4CAMNNlHNl4YXhF91ag==
694+
"@sentry/utils@6.15.0":
695+
version "6.15.0"
696+
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.15.0.tgz#0c247cb092b1796d39c3d16d8e6977b9cdab9ca2"
697+
integrity sha512-gnhKKyFtnNmKWjDizo7VKD0/Vx8cgW1lCusM6WI7jy2jlO3bQA0+Dzgmr4mIReZ74mq4VpOd2Vfrx7ZldW1DMw==
698698
dependencies:
699-
"@sentry/types" "6.13.3"
699+
"@sentry/types" "6.15.0"
700700
tslib "^1.9.3"
701701

702702
"@sinonjs/commons@^1", "@sinonjs/commons@^1.3.0", "@sinonjs/commons@^1.4.0", "@sinonjs/commons@^1.7.0":

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"generate-backup-collections": "TS_NODE_PROJECT=tsconfig.json ts-node -r tsconfig-paths/register tools/generate-backup-collections.ts ./firebase/"
1111
},
1212
"dependencies": {
13+
"@sentry/node": "^6.15.0",
1314
"firebase": "^7.20.0"
1415
},
1516
"devDependencies": {

tools/common.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import ContentSharingStorage from '@worldbrain/memex-common/lib/content-sharing/
99
import ContentConversationStorage from '@worldbrain/memex-common/lib/content-conversations/storage'
1010
import UserManagementStorage from '@worldbrain/memex-common/lib/user-management/storage'
1111
import PersonalCloudStorage from '@worldbrain/memex-common/lib/personal-cloud/storage'
12+
import PersonalAnalyticsStorage from '@worldbrain/memex-common/lib/analytics/storage'
1213
import { registerModuleMapCollections } from '@worldbrain/storex-pattern-modules'
1314

1415
export async function createStorage() {
@@ -22,6 +23,7 @@ export async function createStorage() {
2223
sharedSyncLog: new SharedSyncLogStorage({ storageManager: serverStorageManager, autoPkType: 'string' }),
2324
activityStream: new ActivityStreamStorage({ storageManager: serverStorageManager }),
2425
activityFollows: new ActivityFollowsStorage({ storageManager: serverStorageManager }),
26+
analytics: new PersonalAnalyticsStorage({ storageManager: serverStorageManager }),
2527
contentSharing: contentSharing,
2628
contentConversations: new ContentConversationStorage({
2729
contentSharing,

0 commit comments

Comments
 (0)