@abtnode/webapp 1.8.63-beta-c51e554d → 1.8.63-beta-b71f5f80

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 (198) hide show
  1. package/api/gql/config.js +392 -0
  2. package/api/gql/index.js +102 -0
  3. package/api/gql/middlewares/create-audit-log.js +3 -0
  4. package/api/gql/middlewares/get-blocklet-list.js +14 -0
  5. package/api/gql/middlewares/install-blocklet.js +13 -0
  6. package/api/gql/middlewares/verify-blocklet.js +21 -0
  7. package/api/gql/middlewares/verify-team.js +9 -0
  8. package/api/index.js +249 -0
  9. package/api/libs/auth.js +78 -0
  10. package/api/libs/env.js +3 -0
  11. package/api/libs/login.js +212 -0
  12. package/api/libs/security.js +90 -0
  13. package/api/libs/storage.js +69 -0
  14. package/api/middlewares/mutate-blocklet-permission.js +18 -0
  15. package/api/routes/auth/accept-server.js +28 -0
  16. package/api/routes/auth/connect-owner.js +143 -0
  17. package/api/routes/auth/delegate-transfer-owner-nft.js +86 -0
  18. package/api/routes/auth/invite.js +93 -0
  19. package/api/routes/auth/issue-passport.js +61 -0
  20. package/api/routes/auth/launch-free-blocklet-by-nft.js +9 -0
  21. package/api/routes/auth/launch-free-blocklet.js +9 -0
  22. package/api/routes/auth/launch-paid-blocklet-by-nft.js +9 -0
  23. package/api/routes/auth/launch-paid-blocklet.js +9 -0
  24. package/api/routes/auth/login.js +63 -0
  25. package/api/routes/auth/lost-passport-issue.js +5 -0
  26. package/api/routes/auth/lost-passport-list.js +5 -0
  27. package/api/routes/auth/switch-passport.js +47 -0
  28. package/api/routes/auth/switch-profile.js +69 -0
  29. package/api/routes/auth/util.js +135 -0
  30. package/api/routes/auth/verify-owner.js +39 -0
  31. package/api/routes/auth/verify-purchase.js +185 -0
  32. package/api/routes/blocklet-info.js +246 -0
  33. package/api/routes/blocklet-preference.js +161 -0
  34. package/api/routes/blocklet-proxy.js +220 -0
  35. package/api/routes/did-resolver.js +38 -0
  36. package/api/routes/dns-resolver.js +73 -0
  37. package/api/routes/log.js +31 -0
  38. package/api/routes/passport.js +19 -0
  39. package/api/routes/session.js +61 -0
  40. package/api/routes/user.js +38 -0
  41. package/api/util/find-routing-rule.js +95 -0
  42. package/api/util/get-configs.js +31 -0
  43. package/api/util/index.js +5 -0
  44. package/api/util/navigation.js +84 -0
  45. package/api/webpack.blocklet.js +43 -0
  46. package/api/ws/index.js +146 -0
  47. package/blocklet.yml +1 -1
  48. package/package.json +1 -1
  49. package/build/asset-manifest.json +0 -93
  50. package/build/favicon.ico +0 -0
  51. package/build/icons/css/all.css +0 -5919
  52. package/build/icons/css/brands.css +0 -14
  53. package/build/icons/css/brands.min.css +0 -12
  54. package/build/icons/css/fontawesome.css +0 -7816
  55. package/build/icons/css/fontawesome.min.css +0 -5864
  56. package/build/icons/css/light.css +0 -15
  57. package/build/icons/css/light.min.css +0 -13
  58. package/build/icons/webfonts/fa-brands-400.eot +0 -0
  59. package/build/icons/webfonts/fa-brands-400.svg +0 -1256
  60. package/build/icons/webfonts/fa-brands-400.ttf +0 -0
  61. package/build/icons/webfonts/fa-brands-400.woff +0 -0
  62. package/build/icons/webfonts/fa-brands-400.woff2 +0 -0
  63. package/build/icons/webfonts/fa-light-300.eot +0 -0
  64. package/build/icons/webfonts/fa-light-300.svg +0 -4445
  65. package/build/icons/webfonts/fa-light-300.ttf +0 -0
  66. package/build/icons/webfonts/fa-light-300.woff +0 -0
  67. package/build/icons/webfonts/fa-light-300.woff2 +0 -0
  68. package/build/images/blocklet.png +0 -0
  69. package/build/images/blocklets-00c2c4.png +0 -0
  70. package/build/images/blocklets-222222.png +0 -0
  71. package/build/images/celebrate.png +0 -0
  72. package/build/images/community.svg +0 -6
  73. package/build/images/console-00c2c4.png +0 -0
  74. package/build/images/console-222222.png +0 -0
  75. package/build/images/dashboard-00c2c4.png +0 -0
  76. package/build/images/dashboard-222222.png +0 -0
  77. package/build/images/doc-222222.png +0 -0
  78. package/build/images/hourglass-222222.png +0 -0
  79. package/build/images/https-certificate-icon.png +0 -0
  80. package/build/images/labs-00c2c4.png +0 -0
  81. package/build/images/labs-222222.png +0 -0
  82. package/build/images/log-00c2c4.png +0 -0
  83. package/build/images/log-222222.png +0 -0
  84. package/build/images/member-222222.png +0 -0
  85. package/build/images/node.png +0 -0
  86. package/build/images/official.svg +0 -1
  87. package/build/images/private-222222.png +0 -0
  88. package/build/images/public-222222.png +0 -0
  89. package/build/images/public_avatar.png +0 -0
  90. package/build/images/router-00c2c4.png +0 -0
  91. package/build/images/router-222222.png +0 -0
  92. package/build/images/settings-00c2c4.png +0 -0
  93. package/build/images/settings-222222.png +0 -0
  94. package/build/images/slack.png +0 -0
  95. package/build/images/storage-222222.png +0 -0
  96. package/build/images/store-00c2c4.png +0 -0
  97. package/build/images/store-222222.png +0 -0
  98. package/build/images/team-00c2c4.png +0 -0
  99. package/build/images/team-222222.png +0 -0
  100. package/build/images/time-222222.png +0 -0
  101. package/build/images/upgrade.png +0 -0
  102. package/build/index.html +0 -1
  103. package/build/manifest.json +0 -15
  104. package/build/static/css/4381.5ade355d.chunk.css +0 -1
  105. package/build/static/css/4691.56c2f951.chunk.css +0 -1
  106. package/build/static/css/5245.5d6e9197.chunk.css +0 -1
  107. package/build/static/css/8213.f696fdbf.chunk.css +0 -1
  108. package/build/static/css/9779.f696fdbf.chunk.css +0 -1
  109. package/build/static/css/main.c9e90622.css +0 -1
  110. package/build/static/images/logo.png +0 -0
  111. package/build/static/js/1057.8280393f.chunk.js +0 -1
  112. package/build/static/js/1361.85e46159.chunk.js +0 -1
  113. package/build/static/js/1366.2f174c9b.chunk.js +0 -2
  114. package/build/static/js/1366.2f174c9b.chunk.js.LICENSE.txt +0 -37
  115. package/build/static/js/154.94956824.chunk.js +0 -1
  116. package/build/static/js/1826.07c285de.chunk.js +0 -1
  117. package/build/static/js/2129.120e36ae.chunk.js +0 -1
  118. package/build/static/js/2308.b65bc299.chunk.js +0 -1
  119. package/build/static/js/2564.eef717f3.chunk.js +0 -1
  120. package/build/static/js/2657.d3c62d57.chunk.js +0 -1
  121. package/build/static/js/2720.26eb1788.chunk.js +0 -1
  122. package/build/static/js/2828.4f318970.chunk.js +0 -1
  123. package/build/static/js/2878.5626558d.chunk.js +0 -1
  124. package/build/static/js/3111.84e02823.chunk.js +0 -1
  125. package/build/static/js/3476.c0b3411b.chunk.js +0 -1
  126. package/build/static/js/3633.8c7cf02d.chunk.js +0 -1
  127. package/build/static/js/3732.f5d8b39b.chunk.js +0 -1
  128. package/build/static/js/3776.1490b0f7.chunk.js +0 -1
  129. package/build/static/js/3802.8ecd1e74.chunk.js +0 -2
  130. package/build/static/js/3802.8ecd1e74.chunk.js.LICENSE.txt +0 -194
  131. package/build/static/js/3829.b6d6cf45.chunk.js +0 -1
  132. package/build/static/js/4074.19db40ec.chunk.js +0 -1
  133. package/build/static/js/4104.b47ae0e1.chunk.js +0 -1
  134. package/build/static/js/4241.83e4f741.chunk.js +0 -1
  135. package/build/static/js/4274.e18ffddd.chunk.js +0 -1
  136. package/build/static/js/4349.7c2f6507.chunk.js +0 -1
  137. package/build/static/js/4381.631ef61d.chunk.js +0 -2
  138. package/build/static/js/4381.631ef61d.chunk.js.LICENSE.txt +0 -22
  139. package/build/static/js/4557.3907550e.chunk.js +0 -1
  140. package/build/static/js/4590.5a14012c.chunk.js +0 -1
  141. package/build/static/js/4633.9f946ed5.chunk.js +0 -1
  142. package/build/static/js/4691.550fcb40.chunk.js +0 -2
  143. package/build/static/js/4691.550fcb40.chunk.js.LICENSE.txt +0 -8
  144. package/build/static/js/5074.9ea094a9.chunk.js +0 -1
  145. package/build/static/js/5082.18d16cb9.chunk.js +0 -1
  146. package/build/static/js/519.adae6e43.chunk.js +0 -1
  147. package/build/static/js/556.381dcbd8.chunk.js +0 -1
  148. package/build/static/js/5984.5ed1e6ee.chunk.js +0 -1
  149. package/build/static/js/6158.8a43296d.chunk.js +0 -1
  150. package/build/static/js/6189.d6d74d14.chunk.js +0 -1
  151. package/build/static/js/6239.5620b031.chunk.js +0 -2
  152. package/build/static/js/6239.5620b031.chunk.js.LICENSE.txt +0 -14
  153. package/build/static/js/629.1a7f2553.chunk.js +0 -1
  154. package/build/static/js/6413.ab4a8e01.chunk.js +0 -1
  155. package/build/static/js/6602.c417a217.chunk.js +0 -1
  156. package/build/static/js/6780.64314507.chunk.js +0 -1
  157. package/build/static/js/6830.88b993a0.chunk.js +0 -1
  158. package/build/static/js/6866.2131ea60.chunk.js +0 -2
  159. package/build/static/js/6866.2131ea60.chunk.js.LICENSE.txt +0 -8
  160. package/build/static/js/6898.6fe0c32d.chunk.js +0 -2
  161. package/build/static/js/6898.6fe0c32d.chunk.js.LICENSE.txt +0 -5
  162. package/build/static/js/7016.f26d73d0.chunk.js +0 -1
  163. package/build/static/js/7298.a7286c09.chunk.js +0 -1
  164. package/build/static/js/7327.56a5e016.chunk.js +0 -1
  165. package/build/static/js/744.8b656dd2.chunk.js +0 -1
  166. package/build/static/js/7652.722b9180.chunk.js +0 -1
  167. package/build/static/js/8034.c4dcdeff.chunk.js +0 -1
  168. package/build/static/js/8058.0b2d4727.chunk.js +0 -1
  169. package/build/static/js/8213.fe07b958.chunk.js +0 -1
  170. package/build/static/js/8235.add24931.chunk.js +0 -1
  171. package/build/static/js/8249.63c55b3a.chunk.js +0 -1
  172. package/build/static/js/8262.869cc799.chunk.js +0 -1
  173. package/build/static/js/8352.b57b0e44.chunk.js +0 -1
  174. package/build/static/js/8464.b4b82828.chunk.js +0 -1
  175. package/build/static/js/8606.66db67e2.chunk.js +0 -1
  176. package/build/static/js/9038.2908c176.chunk.js +0 -1
  177. package/build/static/js/9076.db12fce0.chunk.js +0 -1
  178. package/build/static/js/9301.a65db324.chunk.js +0 -2
  179. package/build/static/js/9301.a65db324.chunk.js.LICENSE.txt +0 -8
  180. package/build/static/js/9779.bbf0dd81.chunk.js +0 -1
  181. package/build/static/js/main.8a8e54c6.js +0 -2
  182. package/build/static/js/main.8a8e54c6.js.LICENSE.txt +0 -159
  183. package/build/static/media/iconify.32b54549e843e448ee9b.cjs +0 -2
  184. package/build/static/media/iconify.32b54549e843e448ee9b.cjs.LICENSE.txt +0 -13
  185. package/build/static/media/lato-all-400-normal.3dc1eff492ab1f598560.woff +0 -0
  186. package/build/static/media/lato-all-700-normal.1e7707c9ec98d9b97e7f.woff +0 -0
  187. package/build/static/media/lato-latin-400-normal.be36596da218e1eec01c.woff2 +0 -0
  188. package/build/static/media/lato-latin-700-normal.8f28e0e1fdb195149f1c.woff2 +0 -0
  189. package/build/static/media/lato-latin-ext-400-normal.361f3dbb9db6a5980326.woff2 +0 -0
  190. package/build/static/media/lato-latin-ext-700-normal.9c8812eaec45956201e1.woff2 +0 -0
  191. package/build/static/media/logo.60f66bbe1ce9674a4df4e374c9d97fc4.svg +0 -16
  192. package/build/static/media/ubuntu-mono-all-400-normal.c879328bc62e9c68268f.woff +0 -0
  193. package/build/static/media/ubuntu-mono-cyrillic-400-normal.c367f416832eb8f1b846.woff2 +0 -0
  194. package/build/static/media/ubuntu-mono-cyrillic-ext-400-normal.eda1c4946b1f7bf58386.woff2 +0 -0
  195. package/build/static/media/ubuntu-mono-greek-400-normal.22f3bfc91f79c342bdf4.woff2 +0 -0
  196. package/build/static/media/ubuntu-mono-greek-ext-400-normal.b3459900ea8a25d1f7c2.woff2 +0 -0
  197. package/build/static/media/ubuntu-mono-latin-400-normal.18e32d9d743af28f913e.woff2 +0 -0
  198. package/build/static/media/ubuntu-mono-latin-ext-400-normal.b56e2315611d10838ad5.woff2 +0 -0
@@ -0,0 +1,392 @@
1
+ /* eslint-disable no-await-in-loop */
2
+ const verifyTeam = require('./middlewares/verify-team');
3
+ const verifyBlocklet = require('./middlewares/verify-blocklet');
4
+ const createAuditLog = require('./middlewares/create-audit-log');
5
+ const installBlocklet = require('./middlewares/install-blocklet');
6
+ const getBlockletList = require('./middlewares/get-blocklet-list');
7
+
8
+ const wrap = ([permissions, dataKeys, handler, preHooks = [], postHooks = [], action, node]) => {
9
+ return {
10
+ permissions,
11
+ dataKeys,
12
+ handler: new Proxy(handler, {
13
+ async apply(target, ctx, args) {
14
+ const [input, context] = args;
15
+ // run pre hooks: should abort the request when any hook throws
16
+ for (let i = 0; i < preHooks.length; i++) {
17
+ await Reflect.apply(preHooks[i], ctx, [input, context, node, action]);
18
+ }
19
+
20
+ // run handler
21
+ const result = await Reflect.apply(target, ctx, args);
22
+
23
+ // run post hooks: should not effect the request when any hook throws
24
+ for (let i = 0; i < postHooks.length; i++) {
25
+ Reflect.apply(postHooks[i], ctx, [input, context, node, action, result]);
26
+ }
27
+
28
+ return result;
29
+ },
30
+ }),
31
+ };
32
+ };
33
+
34
+ /**
35
+ * { <gql_api>: [permissions, gql_api_return_key, gql_api_handler] }
36
+ */
37
+ const genConfig = node => {
38
+ const configs = {
39
+ // Blocklet registry
40
+ getBlockletMeta: [['query_blocklets'], 'meta', node.getBlockletMeta],
41
+
42
+ // Blocklet manager
43
+ getBlocklet: [['query_blocklets', 'query_blocklet'], 'blocklet', node.getBlocklet, [verifyBlocklet]],
44
+ getBlocklets: [['query_blocklets'], 'blocklets', node.getBlocklets, [getBlockletList]],
45
+ getBlockletDiff: [['query_blocklets', 'query_blocklet'], 'blockletDiff', node.getBlockletDiff, [verifyBlocklet]],
46
+ getBlockletRuntimeHistory: [
47
+ ['query_blocklets', 'query_blocklet'],
48
+ 'history',
49
+ node.getBlockletRuntimeHistory,
50
+ [verifyBlocklet],
51
+ ],
52
+
53
+ getLatestBlockletVersion: [
54
+ ['query_blocklets', 'query_blocklet'],
55
+ 'data',
56
+ node.getLatestBlockletVersion,
57
+ [verifyBlocklet],
58
+ ],
59
+ getBlockletMetaFromUrl: [[], ['meta', 'isFree', 'inStore', 'registryUrl'], node.getBlockletMetaFromUrl],
60
+ getBlockletByBundle: [
61
+ ['query_blocklets'],
62
+ ['blockletDid', 'isExternal', 'isInstalled', 'isRunning'],
63
+ node.getBlockletByBundle,
64
+ [verifyBlocklet],
65
+ ],
66
+ installBlocklet: [['mutate_blocklets'], 'blocklet', node.installBlocklet, [installBlocklet]],
67
+ installBlockletFromVc: [['mutate_blocklets'], 'blocklet', node.installBlockletFromVc, []],
68
+ installComponent: [
69
+ ['mutate_blocklets', 'mutate_blocklet'],
70
+ 'blocklet',
71
+ node.installComponent,
72
+ [verifyBlocklet],
73
+ [createAuditLog],
74
+ ],
75
+ startBlocklet: [
76
+ ['mutate_blocklets', 'mutate_blocklet'],
77
+ 'blocklet',
78
+ node.startBlocklet,
79
+ [verifyBlocklet],
80
+ [createAuditLog],
81
+ ],
82
+ stopBlocklet: [
83
+ ['mutate_blocklets', 'mutate_blocklet'],
84
+ 'blocklet',
85
+ node.stopBlocklet,
86
+ [verifyBlocklet],
87
+ [createAuditLog],
88
+ ],
89
+ reloadBlocklet: [
90
+ ['mutate_blocklets', 'mutate_blocklet'],
91
+ 'blocklet',
92
+ node.reloadBlocklet,
93
+ [verifyBlocklet],
94
+ [createAuditLog],
95
+ ],
96
+ restartBlocklet: [
97
+ ['mutate_blocklets', 'mutate_blocklet'],
98
+ 'blocklet',
99
+ node.restartBlocklet,
100
+ [verifyBlocklet],
101
+ [createAuditLog],
102
+ ],
103
+ deleteBlocklet: [
104
+ ['mutate_blocklets', 'mutate_blocklet'],
105
+ 'blocklet',
106
+ node.deleteBlocklet,
107
+ [verifyBlocklet],
108
+ [createAuditLog],
109
+ ],
110
+ deleteComponent: [
111
+ ['mutate_blocklets', 'mutate_blocklet'],
112
+ 'blocklet',
113
+ node.deleteComponent,
114
+ [verifyBlocklet],
115
+ [createAuditLog],
116
+ ],
117
+ cancelDownloadBlocklet: [
118
+ ['mutate_blocklets', 'mutate_blocklet'],
119
+ 'blocklet',
120
+ node.cancelDownloadBlocklet,
121
+ [verifyBlocklet],
122
+ [createAuditLog],
123
+ ],
124
+ upgradeBlocklet: [['mutate_blocklets', 'mutate_blocklet'], 'blocklet', node.upgradeBlocklet, [verifyBlocklet]],
125
+ configBlocklet: [
126
+ ['mutate_blocklets', 'mutate_blocklet'],
127
+ 'blocklet',
128
+ node.configBlocklet,
129
+ [verifyBlocklet],
130
+ [createAuditLog],
131
+ ],
132
+ checkComponentsForUpdates: [
133
+ ['mutate_blocklets', 'mutate_blocklet'],
134
+ 'preUpdateInfo',
135
+ node.checkComponentsForUpdates,
136
+ [verifyBlocklet],
137
+ ],
138
+ upgradeComponents: [
139
+ ['mutate_blocklets', 'mutate_blocklet'],
140
+ 'blocklet',
141
+ node.upgradeComponents,
142
+ [verifyBlocklet],
143
+ [createAuditLog],
144
+ ],
145
+ configPublicToStore: [
146
+ ['mutate_blocklets', 'mutate_blocklet'],
147
+ 'blocklet',
148
+ node.configPublicToStore,
149
+ [verifyBlocklet],
150
+ [createAuditLog],
151
+ ],
152
+ configNavigations: [
153
+ ['mutate_blocklets', 'mutate_blocklet'],
154
+ 'blocklet',
155
+ node.configNavigations,
156
+ [verifyBlocklet],
157
+ [createAuditLog],
158
+ ],
159
+ updateWhoCanAccess: [
160
+ ['mutate_blocklets', 'mutate_blocklet'],
161
+ 'blocklet',
162
+ node.updateWhoCanAccess,
163
+ [verifyBlocklet],
164
+ [createAuditLog],
165
+ ],
166
+ updateComponentTitle: [
167
+ ['mutate_blocklets', 'mutate_blocklet'],
168
+ 'blocklet',
169
+ node.updateComponentTitle,
170
+ [verifyBlocklet],
171
+ [createAuditLog],
172
+ ],
173
+ updateComponentMountPoint: [
174
+ ['mutate_blocklets', 'mutate_blocklet'],
175
+ 'blocklet',
176
+ node.updateComponentMountPoint,
177
+ [verifyBlocklet],
178
+ [createAuditLog],
179
+ ],
180
+
181
+ // Team Access Control
182
+ getRoles: [['query_team'], 'roles', node.getRoles, [verifyTeam]],
183
+ createRole: [['mutate_team'], 'role', node.createRole, [verifyTeam], [createAuditLog]],
184
+ updateRole: [['mutate_team'], 'role', node.updateRole, [verifyTeam], [createAuditLog]],
185
+ deleteRole: [['mutate_team'], 'success', node.deleteRole, [verifyTeam], [createAuditLog]],
186
+
187
+ getPermissions: [['query_team'], 'permissions', node.getPermissions, [verifyTeam]],
188
+ createPermission: [['mutate_team'], 'permission', node.createPermission, [verifyTeam], [createAuditLog]],
189
+ updatePermission: [['mutate_team'], 'role', node.updatePermission, [verifyTeam], [createAuditLog]],
190
+ deletePermission: [['mutate_team'], 'success', node.deletePermission, [verifyTeam], [createAuditLog]],
191
+
192
+ grantPermissionForRole: [['mutate_team'], 'success', node.grantPermissionForRole, [verifyTeam], [createAuditLog]],
193
+ revokePermissionFromRole: [
194
+ ['mutate_team'],
195
+ 'success',
196
+ node.revokePermissionFromRole,
197
+ [verifyTeam],
198
+ [createAuditLog],
199
+ ],
200
+ updatePermissionsForRole: [['mutate_team'], 'role', node.updatePermissionsForRole, [verifyTeam], [createAuditLog]],
201
+ getPermissionsByRole: [['query_team'], 'permissions', node.getPermissionsByRole, [verifyTeam]],
202
+ hasPermission: [['query_team'], 'result', node.hasPermission, [verifyTeam]],
203
+
204
+ // Team User
205
+ getUsers: [['query_team'], ['users', 'paging'], node.getUsers, [verifyTeam]],
206
+ getUser: [['query_team'], 'user', node.getUser, [verifyTeam]],
207
+ getUsersCountPerRole: [['query_team'], 'counts', node.getUsersCountPerRole, [verifyTeam]],
208
+ getOwner: [['query_team'], 'user', node.getOwner, [verifyTeam]],
209
+ removeUser: [['mutate_team'], 'user', node.removeUser, [verifyTeam], [createAuditLog]],
210
+ updateUserApproval: [['mutate_team'], 'user', node.updateUserApproval, [verifyTeam], [createAuditLog]],
211
+ updateUserRole: [['mutate_team'], 'user', node.updateUserRole, [verifyTeam], [createAuditLog]],
212
+ getInvitations: [['query_team'], 'invitations', node.getInvitations, [verifyTeam]],
213
+ createMemberInvitation: [
214
+ ['mutate_team'],
215
+ 'inviteInfo',
216
+ node.createMemberInvitation,
217
+ [verifyTeam],
218
+ [createAuditLog],
219
+ ],
220
+ createTransferInvitation: [
221
+ ['mutate_team'],
222
+ 'inviteInfo',
223
+ node.createTransferInvitation,
224
+ [verifyTeam],
225
+ [createAuditLog],
226
+ ],
227
+ deleteInvitation: [['mutate_team'], 'invitation', node.deleteInvitation, [verifyTeam], [createAuditLog]],
228
+
229
+ // Team Passport
230
+ getPassportIssuances: [['query_team'], 'list', node.getPassportIssuances, [verifyTeam]],
231
+ createPassportIssuance: [['mutate_team'], 'info', node.createPassportIssuance, [verifyTeam], [createAuditLog]],
232
+ deletePassportIssuance: [
233
+ ['mutate_team'],
234
+ 'invitation',
235
+ node.deletePassportIssuance,
236
+ [verifyTeam],
237
+ [createAuditLog],
238
+ ],
239
+ issuePassportToUser: [['mutate_team'], 'user', node.issuePassportToUser, [verifyTeam], [createAuditLog]],
240
+ revokeUserPassport: [['mutate_team'], 'user', node.revokeUserPassport, [verifyTeam], [createAuditLog]],
241
+ enableUserPassport: [['mutate_team'], 'user', node.enableUserPassport, [verifyTeam], [createAuditLog]],
242
+ configTrustedPassports: [['mutate_team'], 'info', node.configTrustedPassports, [verifyTeam], [createAuditLog]],
243
+ configPassportIssuance: [['mutate_team'], 'info', node.configPassportIssuance, [verifyTeam], [createAuditLog]],
244
+
245
+ // Team Settings
246
+ addBlockletStore: [['mutate_team'], 'info', node.addBlockletStore, [verifyTeam], [createAuditLog]],
247
+ deleteBlockletStore: [['mutate_team'], 'info', node.deleteBlockletStore, [verifyTeam], [createAuditLog]],
248
+
249
+ // Access Keys
250
+ getAccessKeys: [['query_accessKey'], 'list', node.getAccessKeys],
251
+ createAccessKey: [['mutate_accessKey'], 'data', node.createAccessKey, [], [createAuditLog]],
252
+ deleteAccessKey: [['mutate_accessKey'], 'data', node.deleteAccessKey, [], [createAuditLog]],
253
+ updateAccessKey: [['mutate_accessKey'], 'data', node.updateAccessKey, [], [createAuditLog]],
254
+
255
+ // Router
256
+ getRoutingSites: [['query_router'], 'sites', node.getRoutingSites],
257
+ getRoutingProviders: [['query_router'], 'providers', node.getRoutingProviders],
258
+
259
+ addRoutingSite: [['mutate_router'], 'site', node.addRoutingSite, [], [createAuditLog]],
260
+ deleteRoutingSite: [['mutate_router'], 'site', node.deleteRoutingSite, [], [createAuditLog]],
261
+ updateRoutingSite: [
262
+ ['mutate_router', 'mutate_blocklet'],
263
+ 'site',
264
+ node.updateRoutingSite,
265
+ [verifyBlocklet],
266
+ [createAuditLog],
267
+ ],
268
+
269
+ addRoutingRule: [
270
+ ['mutate_router', 'mutate_blocklet'],
271
+ 'site',
272
+ node.addRoutingRule,
273
+ [verifyBlocklet],
274
+ [createAuditLog],
275
+ ],
276
+ updateRoutingRule: [
277
+ ['mutate_router', 'mutate_blocklet'],
278
+ 'site',
279
+ node.updateRoutingRule,
280
+ [verifyBlocklet],
281
+ [createAuditLog],
282
+ ],
283
+ deleteRoutingRule: [
284
+ ['mutate_router', 'mutate_blocklet'],
285
+ 'site',
286
+ node.deleteRoutingRule,
287
+ [verifyBlocklet],
288
+ [createAuditLog],
289
+ ],
290
+
291
+ addDomainAlias: [
292
+ ['mutate_router', 'mutate_blocklet'],
293
+ 'site',
294
+ node.addDomainAlias,
295
+ [verifyBlocklet],
296
+ [createAuditLog],
297
+ ],
298
+ deleteDomainAlias: [
299
+ ['mutate_router', 'mutate_blocklet'],
300
+ 'site',
301
+ node.deleteDomainAlias,
302
+ [verifyBlocklet],
303
+ [createAuditLog],
304
+ ],
305
+
306
+ // Router Snapshots
307
+ getRoutingSnapshots: [['query_router'], 'snapshots', node.getRoutingSnapshots],
308
+ getSnapshotSites: [['query_router'], 'sites', node.getSnapshotSites],
309
+ takeRoutingSnapshot: [['query_router'], 'hash', node.takeRoutingSnapshot],
310
+
311
+ checkDomains: [['query_router', 'query_blocklet'], 'result', node.checkDomains, [verifyBlocklet]],
312
+ findCertificateByDomain: [
313
+ ['query_router', 'query_blocklet'],
314
+ 'cert',
315
+ node.findCertificateByDomain,
316
+ [verifyBlocklet],
317
+ ],
318
+
319
+ // Router Certificates
320
+ getCertificates: [['query_router', 'query_certificate'], 'certificates', node.getCertificates],
321
+ addCertificate: [['mutate_router', 'mutate_certificate'], 'certificate', node.addCertificate, [], [createAuditLog]],
322
+ updateCertificate: [
323
+ ['mutate_router', 'mutate_certificate'],
324
+ 'certificate',
325
+ node.updateCertificate,
326
+ [],
327
+ [createAuditLog],
328
+ ],
329
+ deleteCertificate: [
330
+ ['mutate_router', 'mutate_certificate'],
331
+ 'certificate',
332
+ node.deleteCertificate,
333
+ [],
334
+ [createAuditLog],
335
+ ],
336
+ issueLetsEncryptCert: [
337
+ ['mutate_certificate', 'mutate_blocklet'],
338
+ 'certificate',
339
+ node.issueLetsEncryptCert,
340
+ [],
341
+ [createAuditLog],
342
+ ],
343
+
344
+ // Gateway
345
+ updateGateway: [['mutate_node'], 'gateway', node.updateGateway, [], [createAuditLog]],
346
+
347
+ // Node
348
+ getNodeInfo: [[], 'info', node.getNodeInfo],
349
+ getNodeEnv: [['query_node'], 'info', node.getNodeEnv],
350
+ updateNodeInfo: [['mutate_node'], 'info', node.updateNodeInfo, [], [createAuditLog]],
351
+ updateNodeRouting: [['mutate_node'], 'info', node.updateNodeRouting, [], [createAuditLog]],
352
+ upgradeNodeVersion: [['mutate_node'], 'sessionId', node.upgradeNodeVersion, [], [createAuditLog]],
353
+ restartServer: [['mutate_node'], 'sessionId', node.restartServer, [], [createAuditLog]],
354
+ checkNodeVersion: [['query_node'], 'version', node.checkNodeVersion],
355
+ resetNode: [['mutate_node'], 'info', node.resetNode],
356
+ getDelegationState: [[], 'state', node.getDelegationState],
357
+ // why use query_node: any member in server can reset node status to running
358
+ resetNodeStatus: [['query_node'], 'info', node.resetNodeStatus],
359
+ getNodeRuntimeHistory: [['query_node'], 'history', node.getNodeRuntimeHistory],
360
+
361
+ // Node Session
362
+ getSession: [['query_session'], 'session', node.getSession],
363
+ startSession: [['mutate_session'], 'session', node.startSession],
364
+ updateSession: [['mutate_session'], 'session', node.updateSession],
365
+ endSession: [['mutate_session'], 'session', node.endSession],
366
+
367
+ // Notifications
368
+ getNotifications: [['query_notification'], ['list', 'paging'], node.getNotifications],
369
+ readNotifications: [['mutate_notification'], 'numAffected', node.readNotifications],
370
+ unreadNotifications: [['mutate_notification'], 'numAffected', node.unreadNotifications],
371
+
372
+ // Webhook
373
+ getWebHooks: [['query_webhook'], 'webhooks', node.getWebHooks],
374
+ createWebHook: [['mutate_webhook'], 'webhook', node.createWebHook, [], [createAuditLog]],
375
+ deleteWebHook: [['mutate_webhook'], 'data', node.deleteWebHook, [], [createAuditLog]],
376
+ getWebhookSenders: [['query_webhook'], 'senders', node.getWebhookSenders],
377
+ sendTestMessage: [['mutate_webhook'], 'data', node.sendTestMessage],
378
+
379
+ // Audit logs
380
+ getAuditLogs: [['query_node', 'query_blocklet'], ['list', 'paging'], node.getAuditLogs, [verifyBlocklet]],
381
+ };
382
+
383
+ return Object.freeze(
384
+ Object.keys(configs).reduce((acc, k) => {
385
+ const [permissions, dataKeys, handler, preHooks = [], postHooks = []] = configs[k];
386
+ acc[k] = wrap([permissions, dataKeys, handler, preHooks, postHooks, k, node]);
387
+ return acc;
388
+ }, {})
389
+ );
390
+ };
391
+
392
+ module.exports = genConfig;
@@ -0,0 +1,102 @@
1
+ /* eslint-disable default-param-last */
2
+ const cloneDeep = require('lodash/cloneDeep');
3
+ const { graphqlHTTP } = require('express-graphql');
4
+ const GraphQLUpload = require('graphql-upload/GraphQLUpload.js');
5
+ const { makeExecutableSchema } = require('@graphql-tools/schema');
6
+ const { wipeSensitiveData, fixBlockletStatus } = require('@blocklet/meta/lib/util');
7
+ const formatContext = require('@abtnode/util/lib/format-context');
8
+ const schemaSource = require('@abtnode/schema');
9
+ const logger = require('@abtnode/logger')('@abtnode/gql');
10
+ const genConfig = require('./config');
11
+
12
+ const wrapResolver = async ({ name, dataKeys, callback }) => {
13
+ const t = Date.now();
14
+ try {
15
+ const result = await callback();
16
+
17
+ const resultsMap = {};
18
+ if (Array.isArray(dataKeys)) {
19
+ dataKeys.forEach(dataKey => {
20
+ resultsMap[dataKey] = result[dataKey];
21
+ });
22
+ } else {
23
+ resultsMap[dataKeys] = result;
24
+ }
25
+
26
+ if (dataKeys === 'blocklet') {
27
+ const d = cloneDeep(result);
28
+ fixBlockletStatus(d);
29
+ resultsMap[dataKeys] = wipeSensitiveData(d);
30
+ }
31
+
32
+ if (dataKeys === 'blocklets') {
33
+ resultsMap[dataKeys] = cloneDeep(result || []).map(blocklet => {
34
+ fixBlockletStatus(blocklet);
35
+ return wipeSensitiveData(blocklet);
36
+ });
37
+ }
38
+
39
+ // performance metrics
40
+ const ms = Date.now() - t;
41
+ if (ms > 2000) {
42
+ logger.warn('graphql resolver latency', { api: name, time: `${ms}ms` });
43
+ }
44
+
45
+ return {
46
+ code: 'ok',
47
+ ...resultsMap,
48
+ };
49
+ /* istanbul ignore next */
50
+ } catch (error) {
51
+ logger.error('graphql resolver error', { error });
52
+ throw error;
53
+ }
54
+ };
55
+
56
+ /**
57
+ * @param {object} configs { <api>: { dataKeys, handler } }
58
+ * @param {boolean} graphiql
59
+ */
60
+ const createMiddleware = (configs = {}, graphiql = true) => {
61
+ /* istanbul ignore next */
62
+ const specials = {
63
+ addRoutingSite: input => ({ site: input }),
64
+ };
65
+
66
+ const resolvers = Object.entries(configs).reduce((acc, [api, { dataKeys, handler }]) => {
67
+ if (specials[api]) {
68
+ acc[api] = ({ input } = {}, ctx) =>
69
+ wrapResolver({ name: api, dataKeys, callback: () => handler(specials[api](input), formatContext(ctx)) });
70
+ } else {
71
+ acc[api] = ({ input } = {}, ctx) =>
72
+ wrapResolver({ name: api, dataKeys, callback: () => handler(input, formatContext(ctx)) });
73
+ }
74
+
75
+ return acc;
76
+ }, {});
77
+
78
+ return graphqlHTTP({
79
+ schema: makeExecutableSchema({
80
+ typeDefs: schemaSource,
81
+ resolvers: {
82
+ Upload: GraphQLUpload,
83
+ },
84
+ }),
85
+ customFormatErrorFn: error => {
86
+ logger.error('graphql error', { error });
87
+ return {
88
+ message: error.message,
89
+ locations: error.locations,
90
+ stack: error.stack ? error.stack.split('\n') : [],
91
+ path: error.path,
92
+ };
93
+ },
94
+ rootValue: resolvers,
95
+ graphiql,
96
+ });
97
+ };
98
+
99
+ module.exports = createMiddleware;
100
+ module.exports.wrapResolver = wrapResolver;
101
+ module.exports.formatContext = formatContext;
102
+ module.exports.genConfig = genConfig;
@@ -0,0 +1,3 @@
1
+ module.exports = (args, context, node, action, result) => {
2
+ node.createAuditLog({ action, args, context, result }).catch(err => console.error('create audit log error', err));
3
+ };
@@ -0,0 +1,14 @@
1
+ const { SERVER_ROLES } = require('@abtnode/constant');
2
+
3
+ module.exports = (input, context) => {
4
+ const { role } = context.user;
5
+
6
+ if (role === SERVER_ROLES.EXTERNAL_BLOCKLETS_MANAGER) {
7
+ input.filter = 'external-only';
8
+ return;
9
+ }
10
+
11
+ if (role !== SERVER_ROLES.OWNER) {
12
+ input.filter = 'external-excluded';
13
+ }
14
+ };
@@ -0,0 +1,13 @@
1
+ /* eslint-disable no-unused-vars */
2
+ // const { SERVER_ROLES } = require('@abtnode/constant');
3
+
4
+ // Currently this middleware is not used
5
+ module.exports = (input, context) => {
6
+ // const { did, role, controller } = context.user;
7
+ // if (role === SERVER_ROLES.EXTERNAL_BLOCKLET_CONTROLLER) {
8
+ // input.controller = {
9
+ // ...controller,
10
+ // id: did,
11
+ // };
12
+ // }
13
+ };
@@ -0,0 +1,21 @@
1
+ const { isBlockletRole } = require('@abtnode/constant');
2
+
3
+ module.exports = ({ did, rootDid, scope, teamDid }, context) => {
4
+ const { role, blockletDid } = context.user;
5
+
6
+ let id;
7
+ if (rootDid) {
8
+ id = rootDid;
9
+ } else if (teamDid) {
10
+ id = teamDid;
11
+ } else if (scope) {
12
+ // e.g. scope is blocklet did in getAuditLog
13
+ id = scope;
14
+ } else if (did) {
15
+ id = Array.isArray(did) ? did[0] : did;
16
+ }
17
+
18
+ if (isBlockletRole(role) && blockletDid !== id) {
19
+ throw new Error("You cannot request other blocklet's data");
20
+ }
21
+ };
@@ -0,0 +1,9 @@
1
+ const { isBlockletRole } = require('@abtnode/constant');
2
+
3
+ module.exports = ({ teamDid }, context) => {
4
+ const { role, blockletDid } = context.user;
5
+
6
+ if (isBlockletRole(role) && blockletDid !== teamDid) {
7
+ throw new Error("You cannot request other blocklet's data");
8
+ }
9
+ };