@casual-simulation/aux-records 3.4.6-alpha.14668890889 → 3.5.0-alpha.15119114602
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AIController.js +835 -890
- package/AIController.js.map +1 -1
- package/AIHumeInterface.js +43 -54
- package/AIHumeInterface.js.map +1 -1
- package/AIOpenAIRealtimeInterface.js +60 -71
- package/AIOpenAIRealtimeInterface.js.map +1 -1
- package/AnthropicAIChatInterface.js +96 -142
- package/AnthropicAIChatInterface.js.map +1 -1
- package/AuthController.d.ts +3 -2
- package/AuthController.js +1907 -1933
- package/AuthController.js.map +1 -1
- package/AuthStore.d.ts +1 -10
- package/BlockadeLabsGenerateSkyboxInterface.js +57 -72
- package/BlockadeLabsGenerateSkyboxInterface.js.map +1 -1
- package/CachingConfigStore.js +30 -45
- package/CachingConfigStore.js.map +1 -1
- package/CachingPolicyStore.d.ts +8 -2
- package/CachingPolicyStore.js +108 -135
- package/CachingPolicyStore.js.map +1 -1
- package/ComIdConfig.d.ts +18 -18
- package/ComIdConfig.js.map +1 -1
- package/ConsoleAuthMessenger.js +7 -20
- package/ConsoleAuthMessenger.js.map +1 -1
- package/DataRecordsController.d.ts +2 -2
- package/DataRecordsController.js +369 -377
- package/DataRecordsController.js.map +1 -1
- package/DataRecordsStore.d.ts +1 -1
- package/DataRecordsStore.js +1 -1
- package/DataRecordsStore.js.map +1 -1
- package/EventRecordsController.js +226 -240
- package/EventRecordsController.js.map +1 -1
- package/FileRecordsController.d.ts +13 -2
- package/FileRecordsController.js +458 -450
- package/FileRecordsController.js.map +1 -1
- package/GoogleAIChatInterface.js +133 -179
- package/GoogleAIChatInterface.js.map +1 -1
- package/LivekitController.js +43 -54
- package/LivekitController.js.map +1 -1
- package/LoomController.js +64 -75
- package/LoomController.js.map +1 -1
- package/MemoryAuthMessenger.js +10 -23
- package/MemoryAuthMessenger.js.map +1 -1
- package/MemoryCache.js +18 -35
- package/MemoryCache.js.map +1 -1
- package/MemoryFileRecordsLookup.js +105 -125
- package/MemoryFileRecordsLookup.js.map +1 -1
- package/MemoryModerationJobProvider.js +17 -30
- package/MemoryModerationJobProvider.js.map +1 -1
- package/MemoryRateLimiter.js +12 -27
- package/MemoryRateLimiter.js.map +1 -1
- package/MemoryStore.d.ts +18 -6
- package/MemoryStore.js +1879 -1997
- package/MemoryStore.js.map +1 -1
- package/MetricsStore.d.ts +2 -2
- package/ModerationController.js +186 -200
- package/ModerationController.js.map +1 -1
- package/OpenAIChatInterface.js +105 -135
- package/OpenAIChatInterface.js.map +1 -1
- package/OpenAIImageInterface.js +57 -51
- package/OpenAIImageInterface.js.map +1 -1
- package/PolicyController.d.ts +150 -10
- package/PolicyController.js +1546 -1299
- package/PolicyController.js.map +1 -1
- package/PolicyStore.d.ts +110 -2
- package/PolicyStore.js +36 -1
- package/PolicyStore.js.map +1 -1
- package/PrivoClient.js +398 -435
- package/PrivoClient.js.map +1 -1
- package/RateLimitController.js +25 -36
- package/RateLimitController.js.map +1 -1
- package/RecordsClient.js +51 -74
- package/RecordsClient.js.map +1 -1
- package/RecordsController.d.ts +2 -42
- package/RecordsController.js +1026 -1182
- package/RecordsController.js.map +1 -1
- package/RecordsServer.d.ts +196 -27
- package/RecordsServer.js +1701 -1343
- package/RecordsServer.js.map +1 -1
- package/RecordsStore.d.ts +1 -10
- package/RecordsStore.js.map +1 -1
- package/ServerConfig.d.ts +339 -195
- package/ServerConfig.js +13 -0
- package/ServerConfig.js.map +1 -1
- package/SloydInterface.js +62 -75
- package/SloydInterface.js.map +1 -1
- package/StabilityAIImageInterface.js +150 -167
- package/StabilityAIImageInterface.js.map +1 -1
- package/SubscriptionConfigBuilder.d.ts +6 -1
- package/SubscriptionConfigBuilder.js +22 -0
- package/SubscriptionConfigBuilder.js.map +1 -1
- package/SubscriptionConfiguration.d.ts +266 -169
- package/SubscriptionConfiguration.js +101 -79
- package/SubscriptionConfiguration.js.map +1 -1
- package/SubscriptionController.d.ts +2 -1
- package/SubscriptionController.js +643 -650
- package/SubscriptionController.js.map +1 -1
- package/SystemNotificationMessenger.d.ts +21 -4
- package/SystemNotificationMessenger.js +36 -30
- package/SystemNotificationMessenger.js.map +1 -1
- package/TestUtils.d.ts +9 -1
- package/TestUtils.js +105 -129
- package/TestUtils.js.map +1 -1
- package/Utils.d.ts +2 -16
- package/Utils.js +21 -22
- package/Utils.js.map +1 -1
- package/crud/CrudHelpers.js +17 -26
- package/crud/CrudHelpers.js.map +1 -1
- package/crud/CrudRecordsController.d.ts +1 -1
- package/crud/CrudRecordsController.js +259 -267
- package/crud/CrudRecordsController.js.map +1 -1
- package/crud/CrudRecordsControllerTests.js +174 -185
- package/crud/CrudRecordsControllerTests.js.map +1 -1
- package/crud/CrudRecordsStore.d.ts +7 -3
- package/crud/MemoryCrudRecordsStore.d.ts +4 -4
- package/crud/MemoryCrudRecordsStore.js +98 -118
- package/crud/MemoryCrudRecordsStore.js.map +1 -1
- package/crud/sub/MemorySubCrudRecordsStore.d.ts +24 -0
- package/crud/sub/MemorySubCrudRecordsStore.js +146 -0
- package/crud/sub/MemorySubCrudRecordsStore.js.map +1 -0
- package/crud/sub/SubCrudRecordsController.d.ts +182 -0
- package/crud/sub/SubCrudRecordsController.js +360 -0
- package/crud/sub/SubCrudRecordsController.js.map +1 -0
- package/crud/sub/SubCrudRecordsControllerTests.d.ts +39 -0
- package/crud/sub/SubCrudRecordsControllerTests.js +821 -0
- package/crud/sub/SubCrudRecordsControllerTests.js.map +1 -0
- package/crud/sub/SubCrudRecordsStore.d.ts +95 -0
- package/{forms/index.js → crud/sub/SubCrudRecordsStore.js} +2 -2
- package/crud/sub/SubCrudRecordsStore.js.map +1 -0
- package/crud/sub/index.d.ts +3 -0
- package/crud/sub/index.js +20 -0
- package/{forms → crud/sub}/index.js.map +1 -1
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/notifications/MemoryNotificationRecordsStore.js +189 -198
- package/notifications/MemoryNotificationRecordsStore.js.map +1 -1
- package/notifications/NotificationRecordsController.js +438 -460
- package/notifications/NotificationRecordsController.js.map +1 -1
- package/notifications/NotificationRecordsStore.d.ts +2 -1
- package/notifications/WebPushInterface.d.ts +0 -1
- package/notifications/WebPushInterface.js +0 -1
- package/notifications/WebPushInterface.js.map +1 -1
- package/package.json +6 -6
- package/packages/MemoryPackageRecordsStore.d.ts +10 -0
- package/packages/MemoryPackageRecordsStore.js +38 -0
- package/packages/MemoryPackageRecordsStore.js.map +1 -0
- package/packages/PackageRecordsController.d.ts +26 -0
- package/packages/PackageRecordsController.js +49 -0
- package/packages/PackageRecordsController.js.map +1 -0
- package/packages/PackageRecordsStore.d.ts +32 -0
- package/packages/PackageRecordsStore.js +19 -0
- package/packages/PackageRecordsStore.js.map +1 -0
- package/packages/index.d.ts +4 -0
- package/packages/index.js +21 -0
- package/packages/index.js.map +1 -0
- package/packages/version/MemoryPackageVersionRecordsStore.d.ts +21 -0
- package/packages/version/MemoryPackageVersionRecordsStore.js +177 -0
- package/packages/version/MemoryPackageVersionRecordsStore.js.map +1 -0
- package/packages/version/PackageVersionRecordsController.d.ts +144 -0
- package/packages/version/PackageVersionRecordsController.js +656 -0
- package/packages/version/PackageVersionRecordsController.js.map +1 -0
- package/packages/version/PackageVersionRecordsStore.d.ts +342 -0
- package/packages/version/PackageVersionRecordsStore.js +126 -0
- package/packages/version/PackageVersionRecordsStore.js.map +1 -0
- package/packages/version/index.d.ts +4 -0
- package/packages/version/index.js +21 -0
- package/packages/version/index.js.map +1 -0
- package/tracing/TracingDecorators.js +31 -40
- package/tracing/TracingDecorators.js.map +1 -1
- package/webhooks/MemoryWebhookRecordsStore.js +56 -72
- package/webhooks/MemoryWebhookRecordsStore.js.map +1 -1
- package/webhooks/WebhookEnvironment.d.ts +3 -3
- package/webhooks/WebhookRecordsController.d.ts +2 -1
- package/webhooks/WebhookRecordsController.js +389 -382
- package/webhooks/WebhookRecordsController.js.map +1 -1
- package/webhooks/WebhookRecordsStore.d.ts +2 -1
- package/websockets/InstRecordsStore.d.ts +50 -0
- package/websockets/InstRecordsStore.js +17 -0
- package/websockets/InstRecordsStore.js.map +1 -1
- package/websockets/MemoryTempInstRecordsStore.d.ts +5 -0
- package/websockets/MemoryTempInstRecordsStore.js +168 -179
- package/websockets/MemoryTempInstRecordsStore.js.map +1 -1
- package/websockets/MemoryWebsocketConnectionStore.js +98 -135
- package/websockets/MemoryWebsocketConnectionStore.js.map +1 -1
- package/websockets/MemoryWebsocketMessenger.js +29 -48
- package/websockets/MemoryWebsocketMessenger.js.map +1 -1
- package/websockets/SplitInstRecordsStore.d.ts +4 -1
- package/websockets/SplitInstRecordsStore.js +167 -185
- package/websockets/SplitInstRecordsStore.js.map +1 -1
- package/websockets/TemporaryInstRecordsStore.d.ts +19 -1
- package/websockets/TemporaryInstRecordsStore.js +17 -0
- package/websockets/TemporaryInstRecordsStore.js.map +1 -1
- package/websockets/WebsocketController.d.ts +147 -3
- package/websockets/WebsocketController.js +1735 -1391
- package/websockets/WebsocketController.js.map +1 -1
- package/websockets/index.d.ts +0 -1
- package/websockets/index.js +0 -1
- package/websockets/index.js.map +1 -1
- package/AAGUID.d.ts +0 -11
- package/AAGUID.js +0 -116
- package/AAGUID.js.map +0 -1
- package/AuthUtils.d.ts +0 -162
- package/AuthUtils.js +0 -327
- package/AuthUtils.js.map +0 -1
- package/forms/FormError.d.ts +0 -43
- package/forms/FormError.js +0 -56
- package/forms/FormError.js.map +0 -1
- package/forms/index.d.ts +0 -2
- package/websockets/Utils.d.ts +0 -33
- package/websockets/Utils.js +0 -82
- package/websockets/Utils.js.map +0 -1
package/RecordsServer.js
CHANGED
|
@@ -1,42 +1,3 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
8
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
9
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
10
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
11
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
12
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
13
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
14
|
-
});
|
|
15
|
-
};
|
|
16
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
17
|
-
var t = {};
|
|
18
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
19
|
-
t[p] = s[p];
|
|
20
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
21
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
22
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
23
|
-
t[p[i]] = s[p[i]];
|
|
24
|
-
}
|
|
25
|
-
return t;
|
|
26
|
-
};
|
|
27
|
-
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
|
28
|
-
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
|
29
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
30
|
-
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
31
|
-
return i = {}, verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
32
|
-
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
|
|
33
|
-
function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
|
|
34
|
-
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
35
|
-
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
36
|
-
function fulfill(value) { resume("next", value); }
|
|
37
|
-
function reject(value) { resume("throw", value); }
|
|
38
|
-
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
39
|
-
};
|
|
40
1
|
/* CasualOS is a set of web-based tools designed to facilitate the creation of real-time, multi-user, context-aware interactive experiences.
|
|
41
2
|
*
|
|
42
3
|
* Copyright (c) 2019-2025 Casual Simulation, Inc.
|
|
@@ -54,12 +15,19 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
|
|
|
54
15
|
* You should have received a copy of the GNU Affero General Public License
|
|
55
16
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
56
17
|
*/
|
|
57
|
-
|
|
18
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
22
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
+
};
|
|
24
|
+
import { tryDecodeUriComponent } from './Utils';
|
|
58
25
|
import { INVALID_REQUEST_ERROR_MESSAGE, MAX_EMAIL_ADDRESS_LENGTH, MAX_SMS_ADDRESS_LENGTH, PRIVO_OPEN_ID_PROVIDER, validateSessionKey, } from './AuthController';
|
|
59
|
-
import { isSuperUserRole, parseSessionKey } from '
|
|
26
|
+
import { isSuperUserRole, parseSessionKey, } from '@casual-simulation/aux-common';
|
|
60
27
|
import { z } from 'zod';
|
|
61
28
|
import { HUME_CONFIG, LOOM_CONFIG } from './RecordsStore';
|
|
62
|
-
import {
|
|
29
|
+
import { tryParseJson } from '@casual-simulation/aux-common';
|
|
30
|
+
import { AVAILABLE_PERMISSIONS_VALIDATION, ENTITLEMENT_FEATURE_VALIDATION, ENTITLEMENT_VALIDATION, PRIVATE_MARKER, RESOURCE_KIND_VALIDATION, getProcedureMetadata, procedure, } from '@casual-simulation/aux-common';
|
|
63
31
|
import { AI_CHAT_MESSAGE_SCHEMA } from './AIChatInterface';
|
|
64
32
|
import { WebsocketEventTypes, websocketEventSchema, websocketRequestMessageSchema, } from '@casual-simulation/aux-common/websockets/WebsocketEvents';
|
|
65
33
|
import { DEFAULT_BRANCH_NAME } from '@casual-simulation/aux-common';
|
|
@@ -72,6 +40,7 @@ import { ADDRESS_VALIDATION, COM_ID_VALIDATION, DISPLAY_NAME_VALIDATION, ERASE_D
|
|
|
72
40
|
import { eraseItemProcedure, getItemProcedure, listItemsProcedure, recordItemProcedure, } from './crud/CrudHelpers';
|
|
73
41
|
import { merge, omit } from 'lodash';
|
|
74
42
|
import { PUSH_NOTIFICATION_PAYLOAD, PUSH_SUBSCRIPTION_SCHEMA, } from './notifications';
|
|
43
|
+
import { getPackageVersionSpecifier } from './packages/version/PackageVersionRecordsStore';
|
|
75
44
|
export const NOT_LOGGED_IN_RESULT = {
|
|
76
45
|
success: false,
|
|
77
46
|
errorCode: 'not_logged_in',
|
|
@@ -150,7 +119,7 @@ export class RecordsServer {
|
|
|
150
119
|
get procedures() {
|
|
151
120
|
return this._procedures;
|
|
152
121
|
}
|
|
153
|
-
constructor({ allowedAccountOrigins, allowedApiOrigins, authController, livekitController, recordsController, eventsController, dataController, manualDataController, filesController, subscriptionController, websocketController, websocketRateLimitController, rateLimitController, policyController, aiController, moderationController, loomController, webhooksController, notificationsController, }) {
|
|
122
|
+
constructor({ allowedAccountOrigins, allowedApiOrigins, authController, livekitController, recordsController, eventsController, dataController, manualDataController, filesController, subscriptionController, websocketController, websocketRateLimitController, rateLimitController, policyController, aiController, moderationController, loomController, webhooksController, notificationsController, packagesController, packageVersionController, }) {
|
|
154
123
|
/**
|
|
155
124
|
* The map of paths to routes that they match.
|
|
156
125
|
*/
|
|
@@ -175,6 +144,8 @@ export class RecordsServer {
|
|
|
175
144
|
this._loomController = loomController;
|
|
176
145
|
this._webhooksController = webhooksController;
|
|
177
146
|
this._notificationsController = notificationsController;
|
|
147
|
+
this._packagesController = packagesController;
|
|
148
|
+
this._packageVersionController = packageVersionController;
|
|
178
149
|
this._tracer = trace.getTracer('RecordsServer', typeof GIT_TAG === 'undefined' ? undefined : GIT_TAG);
|
|
179
150
|
this._procedures = this._createProcedures();
|
|
180
151
|
this._setupRoutes();
|
|
@@ -186,12 +157,12 @@ export class RecordsServer {
|
|
|
186
157
|
.inputs(z.object({
|
|
187
158
|
userId: z.string(),
|
|
188
159
|
}))
|
|
189
|
-
.handler(({ userId }, context) =>
|
|
160
|
+
.handler(async ({ userId }, context) => {
|
|
190
161
|
const authorization = context.sessionKey;
|
|
191
162
|
if (!authorization) {
|
|
192
163
|
return NOT_LOGGED_IN_RESULT;
|
|
193
164
|
}
|
|
194
|
-
const result =
|
|
165
|
+
const result = await this._auth.getUserInfo({
|
|
195
166
|
userId,
|
|
196
167
|
sessionKey: authorization,
|
|
197
168
|
});
|
|
@@ -211,14 +182,14 @@ export class RecordsServer {
|
|
|
211
182
|
displayName: result.displayName,
|
|
212
183
|
role: result.role,
|
|
213
184
|
};
|
|
214
|
-
})
|
|
185
|
+
}),
|
|
215
186
|
isEmailValid: procedure()
|
|
216
187
|
.origins('account')
|
|
217
188
|
.http('POST', '/api/v2/email/valid')
|
|
218
189
|
.inputs(z.object({ email: z.string() }))
|
|
219
|
-
.handler(({ email }) =>
|
|
220
|
-
return
|
|
221
|
-
})
|
|
190
|
+
.handler(async ({ email }) => {
|
|
191
|
+
return await this._auth.isValidEmailAddress(email);
|
|
192
|
+
}),
|
|
222
193
|
isDisplayNameValid: procedure()
|
|
223
194
|
.origins('account')
|
|
224
195
|
.http('POST', '/api/v2/displayName/valid')
|
|
@@ -226,27 +197,27 @@ export class RecordsServer {
|
|
|
226
197
|
displayName: z.string(),
|
|
227
198
|
name: NAME_VALIDATION.optional(),
|
|
228
199
|
}))
|
|
229
|
-
.handler(({ displayName, name }) =>
|
|
230
|
-
return
|
|
231
|
-
})
|
|
200
|
+
.handler(async ({ displayName, name }) => {
|
|
201
|
+
return await this._auth.isValidDisplayName(displayName, name);
|
|
202
|
+
}),
|
|
232
203
|
createAccount: procedure()
|
|
233
204
|
.origins('account')
|
|
234
205
|
.http('POST', '/api/v2/createAccount')
|
|
235
206
|
.inputs(z.object({}))
|
|
236
|
-
.handler((_, context) =>
|
|
237
|
-
const validation =
|
|
207
|
+
.handler(async (_, context) => {
|
|
208
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
238
209
|
if (validation.success === false) {
|
|
239
210
|
if (validation.errorCode === 'no_session_key') {
|
|
240
211
|
return NOT_LOGGED_IN_RESULT;
|
|
241
212
|
}
|
|
242
213
|
return validation;
|
|
243
214
|
}
|
|
244
|
-
const result =
|
|
215
|
+
const result = await this._auth.createAccount({
|
|
245
216
|
userRole: validation.role,
|
|
246
217
|
ipAddress: context.ipAddress,
|
|
247
218
|
});
|
|
248
219
|
return result;
|
|
249
|
-
})
|
|
220
|
+
}),
|
|
250
221
|
listSessions: procedure()
|
|
251
222
|
.origins('account')
|
|
252
223
|
.http('GET', '/api/v2/sessions')
|
|
@@ -256,7 +227,7 @@ export class RecordsServer {
|
|
|
256
227
|
userId: z.string().optional(),
|
|
257
228
|
})
|
|
258
229
|
.default({}))
|
|
259
|
-
.handler(({ expireTimeMs, userId }, context) =>
|
|
230
|
+
.handler(async ({ expireTimeMs, userId }, context) => {
|
|
260
231
|
const sessionKey = context.sessionKey;
|
|
261
232
|
if (!sessionKey) {
|
|
262
233
|
return NOT_LOGGED_IN_RESULT;
|
|
@@ -266,44 +237,44 @@ export class RecordsServer {
|
|
|
266
237
|
return UNACCEPTABLE_SESSION_KEY;
|
|
267
238
|
}
|
|
268
239
|
const [sessionKeyUserId] = parsed;
|
|
269
|
-
const result =
|
|
240
|
+
const result = await this._auth.listSessions({
|
|
270
241
|
userId: userId !== null && userId !== void 0 ? userId : sessionKeyUserId,
|
|
271
242
|
sessionKey,
|
|
272
243
|
expireTimeMs,
|
|
273
244
|
});
|
|
274
245
|
return result;
|
|
275
|
-
})
|
|
246
|
+
}),
|
|
276
247
|
replaceSession: procedure()
|
|
277
248
|
.origins('account')
|
|
278
249
|
.http('POST', '/api/v2/replaceSession')
|
|
279
|
-
.handler((_, context) =>
|
|
250
|
+
.handler(async (_, context) => {
|
|
280
251
|
const sessionKey = context.sessionKey;
|
|
281
252
|
if (!sessionKey) {
|
|
282
253
|
return NOT_LOGGED_IN_RESULT;
|
|
283
254
|
}
|
|
284
|
-
const result =
|
|
255
|
+
const result = await this._auth.replaceSession({
|
|
285
256
|
sessionKey: sessionKey,
|
|
286
257
|
ipAddress: context.ipAddress,
|
|
287
258
|
});
|
|
288
259
|
return result;
|
|
289
|
-
})
|
|
260
|
+
}),
|
|
290
261
|
revokeAllSessions: procedure()
|
|
291
262
|
.origins('account')
|
|
292
263
|
.http('POST', '/api/v2/revokeAllSessions')
|
|
293
264
|
.inputs(z.object({
|
|
294
265
|
userId: z.string(),
|
|
295
266
|
}))
|
|
296
|
-
.handler(({ userId }, context) =>
|
|
267
|
+
.handler(async ({ userId }, context) => {
|
|
297
268
|
const authorization = context.sessionKey;
|
|
298
269
|
if (!authorization) {
|
|
299
270
|
return NOT_LOGGED_IN_RESULT;
|
|
300
271
|
}
|
|
301
|
-
const result =
|
|
272
|
+
const result = await this._auth.revokeAllSessions({
|
|
302
273
|
userId: userId,
|
|
303
274
|
sessionKey: authorization,
|
|
304
275
|
});
|
|
305
276
|
return result;
|
|
306
|
-
})
|
|
277
|
+
}),
|
|
307
278
|
revokeSession: procedure()
|
|
308
279
|
.origins('account')
|
|
309
280
|
.http('POST', '/api/v2/revokeSession')
|
|
@@ -312,7 +283,7 @@ export class RecordsServer {
|
|
|
312
283
|
sessionId: z.string().optional(),
|
|
313
284
|
sessionKey: z.string().optional(),
|
|
314
285
|
}))
|
|
315
|
-
.handler(({ userId, sessionId, sessionKey: sessionKeyToRevoke }, context) =>
|
|
286
|
+
.handler(async ({ userId, sessionId, sessionKey: sessionKeyToRevoke }, context) => {
|
|
316
287
|
// Parse the User ID and Session ID from the sessionKey that is provided in
|
|
317
288
|
// session key that should be revoked
|
|
318
289
|
if (!!sessionKeyToRevoke) {
|
|
@@ -326,13 +297,13 @@ export class RecordsServer {
|
|
|
326
297
|
if (!authorization) {
|
|
327
298
|
return NOT_LOGGED_IN_RESULT;
|
|
328
299
|
}
|
|
329
|
-
const result =
|
|
300
|
+
const result = await this._auth.revokeSession({
|
|
330
301
|
userId,
|
|
331
302
|
sessionId,
|
|
332
303
|
sessionKey: authorization,
|
|
333
304
|
});
|
|
334
305
|
return result;
|
|
335
|
-
})
|
|
306
|
+
}),
|
|
336
307
|
completeLogin: procedure()
|
|
337
308
|
.origins('account')
|
|
338
309
|
.http('POST', '/api/v2/completeLogin')
|
|
@@ -341,15 +312,15 @@ export class RecordsServer {
|
|
|
341
312
|
requestId: z.string(),
|
|
342
313
|
code: z.string(),
|
|
343
314
|
}))
|
|
344
|
-
.handler(({ userId, requestId, code }, context) =>
|
|
345
|
-
const result =
|
|
315
|
+
.handler(async ({ userId, requestId, code }, context) => {
|
|
316
|
+
const result = await this._auth.completeLogin({
|
|
346
317
|
userId,
|
|
347
318
|
requestId,
|
|
348
319
|
code,
|
|
349
320
|
ipAddress: context.ipAddress,
|
|
350
321
|
});
|
|
351
322
|
return result;
|
|
352
|
-
})
|
|
323
|
+
}),
|
|
353
324
|
requestLogin: procedure()
|
|
354
325
|
.origins('account')
|
|
355
326
|
.http('POST', '/api/v2/login')
|
|
@@ -357,25 +328,25 @@ export class RecordsServer {
|
|
|
357
328
|
address: z.string(),
|
|
358
329
|
addressType: z.enum(['email', 'phone']),
|
|
359
330
|
}))
|
|
360
|
-
.handler(({ address, addressType }, context) =>
|
|
361
|
-
const result =
|
|
331
|
+
.handler(async ({ address, addressType }, context) => {
|
|
332
|
+
const result = await this._auth.requestLogin({
|
|
362
333
|
address,
|
|
363
334
|
addressType,
|
|
364
335
|
ipAddress: context.ipAddress,
|
|
365
336
|
});
|
|
366
337
|
return result;
|
|
367
|
-
})
|
|
338
|
+
}),
|
|
368
339
|
requestPrivoLogin: procedure()
|
|
369
340
|
.origins('account')
|
|
370
341
|
.http('POST', '/api/v2/login/privo')
|
|
371
342
|
.inputs(z.object({}))
|
|
372
|
-
.handler((_, context) =>
|
|
373
|
-
const result =
|
|
343
|
+
.handler(async (_, context) => {
|
|
344
|
+
const result = await this._auth.requestOpenIDLogin({
|
|
374
345
|
provider: PRIVO_OPEN_ID_PROVIDER,
|
|
375
346
|
ipAddress: context.ipAddress,
|
|
376
347
|
});
|
|
377
348
|
return result;
|
|
378
|
-
})
|
|
349
|
+
}),
|
|
379
350
|
processOAuthCode: procedure()
|
|
380
351
|
.origins('account')
|
|
381
352
|
.http('POST', '/api/v2/oauth/code')
|
|
@@ -383,27 +354,27 @@ export class RecordsServer {
|
|
|
383
354
|
code: z.string().nonempty(),
|
|
384
355
|
state: z.string().nonempty(),
|
|
385
356
|
}))
|
|
386
|
-
.handler(({ code, state }, context) =>
|
|
387
|
-
const result =
|
|
357
|
+
.handler(async ({ code, state }, context) => {
|
|
358
|
+
const result = await this._auth.processOpenIDAuthorizationCode({
|
|
388
359
|
ipAddress: context.ipAddress,
|
|
389
360
|
authorizationCode: code,
|
|
390
361
|
state,
|
|
391
362
|
});
|
|
392
363
|
return result;
|
|
393
|
-
})
|
|
364
|
+
}),
|
|
394
365
|
completeOAuthLogin: procedure()
|
|
395
366
|
.origins('account')
|
|
396
367
|
.http('POST', '/api/v2/oauth/complete')
|
|
397
368
|
.inputs(z.object({
|
|
398
369
|
requestId: z.string().nonempty(),
|
|
399
370
|
}))
|
|
400
|
-
.handler(({ requestId }, context) =>
|
|
401
|
-
const result =
|
|
371
|
+
.handler(async ({ requestId }, context) => {
|
|
372
|
+
const result = await this._auth.completeOpenIDLogin({
|
|
402
373
|
ipAddress: context.ipAddress,
|
|
403
374
|
requestId,
|
|
404
375
|
});
|
|
405
376
|
return result;
|
|
406
|
-
})
|
|
377
|
+
}),
|
|
407
378
|
requestPrivoSignUp: procedure()
|
|
408
379
|
.origins('account')
|
|
409
380
|
.http('POST', '/api/v2/register/privo')
|
|
@@ -414,8 +385,8 @@ export class RecordsServer {
|
|
|
414
385
|
dateOfBirth: z.coerce.date(),
|
|
415
386
|
displayName: DISPLAY_NAME_VALIDATION,
|
|
416
387
|
}))
|
|
417
|
-
.handler(({ email, parentEmail, name, dateOfBirth, displayName }, context) =>
|
|
418
|
-
const result =
|
|
388
|
+
.handler(async ({ email, parentEmail, name, dateOfBirth, displayName }, context) => {
|
|
389
|
+
const result = await this._auth.requestPrivoSignUp({
|
|
419
390
|
email,
|
|
420
391
|
parentEmail,
|
|
421
392
|
name,
|
|
@@ -424,44 +395,44 @@ export class RecordsServer {
|
|
|
424
395
|
ipAddress: context.ipAddress,
|
|
425
396
|
});
|
|
426
397
|
return result;
|
|
427
|
-
})
|
|
398
|
+
}),
|
|
428
399
|
requestPrivacyFeaturesChange: procedure()
|
|
429
400
|
.origins('account')
|
|
430
401
|
.http('POST', '/api/v2/privacyFeatures/change')
|
|
431
402
|
.inputs(z.object({
|
|
432
403
|
userId: z.string(),
|
|
433
404
|
}))
|
|
434
|
-
.handler(({ userId }, context) =>
|
|
405
|
+
.handler(async ({ userId }, context) => {
|
|
435
406
|
const sessionKey = context.sessionKey;
|
|
436
407
|
if (!sessionKey) {
|
|
437
408
|
return NOT_LOGGED_IN_RESULT;
|
|
438
409
|
}
|
|
439
|
-
const result =
|
|
410
|
+
const result = await this._auth.requestPrivacyFeaturesChange({
|
|
440
411
|
userId,
|
|
441
412
|
sessionKey,
|
|
442
413
|
});
|
|
443
414
|
return result;
|
|
444
|
-
})
|
|
415
|
+
}),
|
|
445
416
|
getWebAuthnRegistrationOptions: procedure()
|
|
446
417
|
.origins(true)
|
|
447
418
|
.http('GET', '/api/v2/webauthn/register/options')
|
|
448
|
-
.handler((_, context) =>
|
|
419
|
+
.handler(async (_, context) => {
|
|
449
420
|
var _a, _b, _c, _d, _e, _f;
|
|
450
421
|
// We don't validate origin because the AuthController will validate it based on the allowed
|
|
451
422
|
// relying parties.
|
|
452
|
-
const validation =
|
|
423
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
453
424
|
if (validation.success === false) {
|
|
454
425
|
if (validation.errorCode === 'no_session_key') {
|
|
455
426
|
return NOT_LOGGED_IN_RESULT;
|
|
456
427
|
}
|
|
457
428
|
return validation;
|
|
458
429
|
}
|
|
459
|
-
const result =
|
|
430
|
+
const result = await this._auth.requestWebAuthnRegistration({
|
|
460
431
|
userId: validation.userId,
|
|
461
432
|
originOrHost: (_e = (_c = (_a = context.origin) !== null && _a !== void 0 ? _a : (_b = context.httpRequest) === null || _b === void 0 ? void 0 : _b.headers.origin) !== null && _c !== void 0 ? _c : (_d = context.httpRequest) === null || _d === void 0 ? void 0 : _d.headers['x-dev-proxy-host']) !== null && _e !== void 0 ? _e : (_f = context.httpRequest) === null || _f === void 0 ? void 0 : _f.headers.host,
|
|
462
433
|
});
|
|
463
434
|
return result;
|
|
464
|
-
})
|
|
435
|
+
}),
|
|
465
436
|
registerWebAuthn: procedure()
|
|
466
437
|
.origins(true)
|
|
467
438
|
.http('POST', '/api/v2/webauthn/register')
|
|
@@ -497,38 +468,38 @@ export class RecordsServer {
|
|
|
497
468
|
type: z.literal('public-key'),
|
|
498
469
|
}),
|
|
499
470
|
}))
|
|
500
|
-
.handler(({ response }, context) =>
|
|
501
|
-
var
|
|
471
|
+
.handler(async ({ response }, context) => {
|
|
472
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
502
473
|
// We don't validate origin because the AuthController will validate it based on the allowed
|
|
503
474
|
// relying parties.
|
|
504
|
-
const validation =
|
|
475
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
505
476
|
if (validation.success === false) {
|
|
506
477
|
if (validation.errorCode === 'no_session_key') {
|
|
507
478
|
return NOT_LOGGED_IN_RESULT;
|
|
508
479
|
}
|
|
509
480
|
return validation;
|
|
510
481
|
}
|
|
511
|
-
const result =
|
|
482
|
+
const result = await this._auth.completeWebAuthnRegistration({
|
|
512
483
|
userId: validation.userId,
|
|
513
484
|
response: response,
|
|
514
|
-
originOrHost: (
|
|
515
|
-
userAgent: (
|
|
485
|
+
originOrHost: (_e = (_c = (_a = context.origin) !== null && _a !== void 0 ? _a : (_b = context.httpRequest) === null || _b === void 0 ? void 0 : _b.headers.origin) !== null && _c !== void 0 ? _c : (_d = context.httpRequest) === null || _d === void 0 ? void 0 : _d.headers['x-dev-proxy-host']) !== null && _e !== void 0 ? _e : (_f = context.httpRequest) === null || _f === void 0 ? void 0 : _f.headers.host,
|
|
486
|
+
userAgent: (_g = context.httpRequest) === null || _g === void 0 ? void 0 : _g.headers['user-agent'],
|
|
516
487
|
});
|
|
517
488
|
return result;
|
|
518
|
-
})
|
|
489
|
+
}),
|
|
519
490
|
getWebAuthnLoginOptions: procedure()
|
|
520
491
|
.origins(true)
|
|
521
492
|
.http('GET', '/api/v2/webauthn/login/options')
|
|
522
|
-
.handler((_, context) =>
|
|
493
|
+
.handler(async (_, context) => {
|
|
523
494
|
// We don't validate origin because the AuthController will validate it based on the allowed
|
|
524
495
|
// relying parties.
|
|
525
|
-
var
|
|
526
|
-
const result =
|
|
496
|
+
var _a, _b, _c, _d, _e, _f;
|
|
497
|
+
const result = await this._auth.requestWebAuthnLogin({
|
|
527
498
|
ipAddress: context.ipAddress,
|
|
528
|
-
originOrHost: (
|
|
499
|
+
originOrHost: (_e = (_c = (_a = context.origin) !== null && _a !== void 0 ? _a : (_b = context.httpRequest) === null || _b === void 0 ? void 0 : _b.headers.origin) !== null && _c !== void 0 ? _c : (_d = context.httpRequest) === null || _d === void 0 ? void 0 : _d.headers['x-dev-proxy-host']) !== null && _e !== void 0 ? _e : (_f = context.httpRequest) === null || _f === void 0 ? void 0 : _f.headers.host,
|
|
529
500
|
});
|
|
530
501
|
return result;
|
|
531
|
-
})
|
|
502
|
+
}),
|
|
532
503
|
completeWebAuthnLogin: procedure()
|
|
533
504
|
.origins(true)
|
|
534
505
|
.http('POST', '/api/v2/webauthn/login')
|
|
@@ -558,49 +529,49 @@ export class RecordsServer {
|
|
|
558
529
|
type: z.literal('public-key'),
|
|
559
530
|
}),
|
|
560
531
|
}))
|
|
561
|
-
.handler(({ response, requestId }, context) =>
|
|
532
|
+
.handler(async ({ response, requestId }, context) => {
|
|
562
533
|
// We don't validate origin because the AuthController will validate it based on the allowed
|
|
563
534
|
// relying parties.
|
|
564
|
-
var
|
|
565
|
-
const result =
|
|
535
|
+
var _a, _b, _c, _d, _e, _f;
|
|
536
|
+
const result = await this._auth.completeWebAuthnLogin({
|
|
566
537
|
requestId: requestId,
|
|
567
538
|
ipAddress: context.ipAddress,
|
|
568
539
|
response: response,
|
|
569
|
-
originOrHost: (
|
|
540
|
+
originOrHost: (_e = (_c = (_a = context.origin) !== null && _a !== void 0 ? _a : (_b = context.httpRequest) === null || _b === void 0 ? void 0 : _b.headers.origin) !== null && _c !== void 0 ? _c : (_d = context.httpRequest) === null || _d === void 0 ? void 0 : _d.headers['x-dev-proxy-host']) !== null && _e !== void 0 ? _e : (_f = context.httpRequest) === null || _f === void 0 ? void 0 : _f.headers.host,
|
|
570
541
|
});
|
|
571
542
|
return result;
|
|
572
|
-
})
|
|
543
|
+
}),
|
|
573
544
|
listUserAuthenticators: procedure()
|
|
574
545
|
.origins('account')
|
|
575
546
|
.http('GET', '/api/v2/webauthn/authenticators')
|
|
576
|
-
.handler((_, context) =>
|
|
577
|
-
const validation =
|
|
547
|
+
.handler(async (_, context) => {
|
|
548
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
578
549
|
if (validation.success === false) {
|
|
579
550
|
if (validation.errorCode === 'no_session_key') {
|
|
580
551
|
return NOT_LOGGED_IN_RESULT;
|
|
581
552
|
}
|
|
582
553
|
return validation;
|
|
583
554
|
}
|
|
584
|
-
const result =
|
|
555
|
+
const result = await this._auth.listUserAuthenticators(validation.userId);
|
|
585
556
|
return result;
|
|
586
|
-
})
|
|
557
|
+
}),
|
|
587
558
|
deleteUserAuthenticator: procedure()
|
|
588
559
|
.origins('account')
|
|
589
560
|
.http('POST', '/api/v2/webauthn/authenticators/delete')
|
|
590
561
|
.inputs(z.object({
|
|
591
562
|
authenticatorId: z.string().nonempty(),
|
|
592
563
|
}))
|
|
593
|
-
.handler(({ authenticatorId }, context) =>
|
|
594
|
-
const validation =
|
|
564
|
+
.handler(async ({ authenticatorId }, context) => {
|
|
565
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
595
566
|
if (validation.success === false) {
|
|
596
567
|
if (validation.errorCode === 'no_session_key') {
|
|
597
568
|
return NOT_LOGGED_IN_RESULT;
|
|
598
569
|
}
|
|
599
570
|
return validation;
|
|
600
571
|
}
|
|
601
|
-
const result =
|
|
572
|
+
const result = await this._auth.deleteUserAuthenticator(validation.userId, authenticatorId);
|
|
602
573
|
return result;
|
|
603
|
-
})
|
|
574
|
+
}),
|
|
604
575
|
createMeetToken: procedure()
|
|
605
576
|
.origins('api')
|
|
606
577
|
.http('POST', '/api/v2/meet/token')
|
|
@@ -608,10 +579,10 @@ export class RecordsServer {
|
|
|
608
579
|
roomName: z.string(),
|
|
609
580
|
userName: z.string(),
|
|
610
581
|
}))
|
|
611
|
-
.handler(({ roomName, userName }) =>
|
|
612
|
-
const result =
|
|
582
|
+
.handler(async ({ roomName, userName }) => {
|
|
583
|
+
const result = await this._livekit.issueToken(roomName, userName);
|
|
613
584
|
return result;
|
|
614
|
-
})
|
|
585
|
+
}),
|
|
615
586
|
createRecord: procedure()
|
|
616
587
|
.origins('account')
|
|
617
588
|
.http('POST', '/api/v2/records')
|
|
@@ -632,7 +603,7 @@ export class RecordsServer {
|
|
|
632
603
|
.nonempty('studioId must not be empty.')
|
|
633
604
|
.optional(),
|
|
634
605
|
}))
|
|
635
|
-
.handler(({ recordName, ownerId, studioId }, context) =>
|
|
606
|
+
.handler(async ({ recordName, ownerId, studioId }, context) => {
|
|
636
607
|
if (!recordName || typeof recordName !== 'string') {
|
|
637
608
|
return {
|
|
638
609
|
success: false,
|
|
@@ -640,21 +611,21 @@ export class RecordsServer {
|
|
|
640
611
|
errorMessage: 'recordName is required and must be a string.',
|
|
641
612
|
};
|
|
642
613
|
}
|
|
643
|
-
const validation =
|
|
614
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
644
615
|
if (validation.success === false) {
|
|
645
616
|
if (validation.errorCode === 'no_session_key') {
|
|
646
617
|
return NOT_LOGGED_IN_RESULT;
|
|
647
618
|
}
|
|
648
619
|
return validation;
|
|
649
620
|
}
|
|
650
|
-
const result =
|
|
621
|
+
const result = await this._records.createRecord({
|
|
651
622
|
recordName,
|
|
652
623
|
ownerId,
|
|
653
624
|
studioId,
|
|
654
625
|
userId: validation.userId,
|
|
655
626
|
});
|
|
656
627
|
return result;
|
|
657
|
-
})
|
|
628
|
+
}),
|
|
658
629
|
addEventCount: procedure()
|
|
659
630
|
.origins('api')
|
|
660
631
|
.http('POST', '/api/v2/records/events/count')
|
|
@@ -667,16 +638,16 @@ export class RecordsServer {
|
|
|
667
638
|
}),
|
|
668
639
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
669
640
|
}))
|
|
670
|
-
.handler(({ recordKey, eventName, count, instances }, context) =>
|
|
671
|
-
const validation =
|
|
641
|
+
.handler(async ({ recordKey, eventName, count, instances }, context) => {
|
|
642
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
672
643
|
if (validation.success === false &&
|
|
673
644
|
validation.errorCode !== 'no_session_key') {
|
|
674
645
|
return validation;
|
|
675
646
|
}
|
|
676
647
|
const userId = validation.userId;
|
|
677
|
-
const result =
|
|
648
|
+
const result = await this._events.addCount(recordKey, eventName, count, userId, instances);
|
|
678
649
|
return result;
|
|
679
|
-
})
|
|
650
|
+
}),
|
|
680
651
|
getEventCount: procedure()
|
|
681
652
|
.origins('api')
|
|
682
653
|
.http('GET', '/api/v2/records/events/count')
|
|
@@ -690,16 +661,16 @@ export class RecordsServer {
|
|
|
690
661
|
.nonempty('eventName must not be empty'),
|
|
691
662
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
692
663
|
}))
|
|
693
|
-
.handler(({ recordName, eventName, instances }, context) =>
|
|
694
|
-
const validation =
|
|
664
|
+
.handler(async ({ recordName, eventName, instances }, context) => {
|
|
665
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
695
666
|
if (validation.success === false &&
|
|
696
667
|
validation.errorCode !== 'no_session_key') {
|
|
697
668
|
return validation;
|
|
698
669
|
}
|
|
699
670
|
const userId = validation.userId;
|
|
700
|
-
const result =
|
|
671
|
+
const result = await this._events.getCount(recordName, eventName, userId, instances);
|
|
701
672
|
return result;
|
|
702
|
-
})
|
|
673
|
+
}),
|
|
703
674
|
listEvents: procedure()
|
|
704
675
|
.origins('api')
|
|
705
676
|
.http('GET', '/api/v2/records/events/list')
|
|
@@ -714,16 +685,16 @@ export class RecordsServer {
|
|
|
714
685
|
.optional(),
|
|
715
686
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
716
687
|
}))
|
|
717
|
-
.handler(({ recordName, eventName, instances }, context) =>
|
|
718
|
-
const validation =
|
|
688
|
+
.handler(async ({ recordName, eventName, instances }, context) => {
|
|
689
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
719
690
|
if (validation.success === false &&
|
|
720
691
|
validation.errorCode !== 'no_session_key') {
|
|
721
692
|
return validation;
|
|
722
693
|
}
|
|
723
694
|
const userId = validation.userId;
|
|
724
|
-
const result =
|
|
695
|
+
const result = await this._events.listEvents(recordName, eventName, userId, instances);
|
|
725
696
|
return result;
|
|
726
|
-
})
|
|
697
|
+
}),
|
|
727
698
|
updateEvent: procedure()
|
|
728
699
|
.origins('api')
|
|
729
700
|
.http('POST', '/api/v2/records/events')
|
|
@@ -734,14 +705,14 @@ export class RecordsServer {
|
|
|
734
705
|
markers: MARKERS_VALIDATION.optional(),
|
|
735
706
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
736
707
|
}))
|
|
737
|
-
.handler(({ recordKey, eventName, count, markers, instances }, context) =>
|
|
738
|
-
const validation =
|
|
708
|
+
.handler(async ({ recordKey, eventName, count, markers, instances }, context) => {
|
|
709
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
739
710
|
if (validation.success === false &&
|
|
740
711
|
validation.errorCode !== 'no_session_key') {
|
|
741
712
|
return validation;
|
|
742
713
|
}
|
|
743
714
|
const userId = validation.userId;
|
|
744
|
-
const result =
|
|
715
|
+
const result = await this._events.updateEvent({
|
|
745
716
|
recordKeyOrRecordName: recordKey,
|
|
746
717
|
userId,
|
|
747
718
|
eventName,
|
|
@@ -750,7 +721,7 @@ export class RecordsServer {
|
|
|
750
721
|
instances,
|
|
751
722
|
});
|
|
752
723
|
return result;
|
|
753
|
-
})
|
|
724
|
+
}),
|
|
754
725
|
deleteManualData: procedure()
|
|
755
726
|
.origins('api')
|
|
756
727
|
.http('DELETE', '/api/v2/records/manual/data')
|
|
@@ -759,42 +730,42 @@ export class RecordsServer {
|
|
|
759
730
|
address: ADDRESS_VALIDATION,
|
|
760
731
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
761
732
|
}))
|
|
762
|
-
.handler((data, context) =>
|
|
733
|
+
.handler(async (data, context) => this._baseEraseRecordData(this._manualData, data, context)),
|
|
763
734
|
getManualData: procedure()
|
|
764
735
|
.origins(true)
|
|
765
736
|
.http('GET', '/api/v2/records/manual/data')
|
|
766
737
|
.inputs(GET_DATA_SCHEMA)
|
|
767
|
-
.handler((data, context) =>
|
|
738
|
+
.handler(async (data, context) => this._baseGetRecordData(this._manualData, data, context)),
|
|
768
739
|
recordManualData: procedure()
|
|
769
740
|
.origins('api')
|
|
770
741
|
.http('POST', '/api/v2/records/manual/data')
|
|
771
742
|
.inputs(RECORD_DATA_SCHEMA)
|
|
772
|
-
.handler((data, context) =>
|
|
743
|
+
.handler(async (data, context) => this._baseRecordData(this._manualData, data, context)),
|
|
773
744
|
getFile: procedure()
|
|
774
745
|
.origins('api')
|
|
775
746
|
.http('GET', '/api/v2/records/file')
|
|
776
747
|
.inputs(READ_FILE_SCHEMA)
|
|
777
|
-
.handler((data, context) =>
|
|
748
|
+
.handler(async (data, context) => this._readFile(data, context)),
|
|
778
749
|
listFiles: procedure()
|
|
779
750
|
.origins('api')
|
|
780
751
|
.http('GET', '/api/v2/records/file/list')
|
|
781
752
|
.inputs(LIST_FILES_SCHEMA)
|
|
782
|
-
.handler((data, context) =>
|
|
753
|
+
.handler(async (data, context) => this._listFiles(data, context)),
|
|
783
754
|
eraseFile: procedure()
|
|
784
755
|
.origins('api')
|
|
785
756
|
.http('DELETE', '/api/v2/records/file')
|
|
786
757
|
.inputs(ERASE_FILE_SCHEMA)
|
|
787
|
-
.handler((data, context) =>
|
|
758
|
+
.handler(async (data, context) => this._eraseFile(data, context)),
|
|
788
759
|
recordFile: procedure()
|
|
789
760
|
.origins('api')
|
|
790
761
|
.http('POST', '/api/v2/records/file')
|
|
791
762
|
.inputs(RECORD_FILE_SCHEMA)
|
|
792
|
-
.handler((data, context) =>
|
|
763
|
+
.handler(async (data, context) => this._recordFile(data, context)),
|
|
793
764
|
updateFile: procedure()
|
|
794
765
|
.origins('api')
|
|
795
766
|
.http('PUT', '/api/v2/records/file')
|
|
796
767
|
.inputs(UPDATE_FILE_SCHEMA)
|
|
797
|
-
.handler((data, context) =>
|
|
768
|
+
.handler(async (data, context) => this._updateFile(data, context)),
|
|
798
769
|
scanFileForModeration: procedure()
|
|
799
770
|
.origins('account')
|
|
800
771
|
.http('POST', '/api/v2/records/file/scan')
|
|
@@ -802,8 +773,8 @@ export class RecordsServer {
|
|
|
802
773
|
recordName: RECORD_NAME_VALIDATION,
|
|
803
774
|
fileName: z.string().min(1),
|
|
804
775
|
}))
|
|
805
|
-
.handler(({ recordName, fileName }, context) =>
|
|
806
|
-
const validation =
|
|
776
|
+
.handler(async ({ recordName, fileName }, context) => {
|
|
777
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
807
778
|
if (validation.success === false) {
|
|
808
779
|
if (validation.errorCode === 'no_session_key') {
|
|
809
780
|
return NOT_LOGGED_IN_RESULT;
|
|
@@ -817,18 +788,18 @@ export class RecordsServer {
|
|
|
817
788
|
errorMessage: 'You are not authorized to perform this action.',
|
|
818
789
|
};
|
|
819
790
|
}
|
|
820
|
-
const result =
|
|
791
|
+
const result = await this._moderationController.scanFile({
|
|
821
792
|
recordName,
|
|
822
793
|
fileName,
|
|
823
794
|
});
|
|
824
795
|
return result;
|
|
825
|
-
})
|
|
796
|
+
}),
|
|
826
797
|
scheduleModerationScans: procedure()
|
|
827
798
|
.origins('account')
|
|
828
799
|
.http('POST', '/api/v2/moderation/schedule/scan')
|
|
829
800
|
.inputs(z.object({}))
|
|
830
|
-
.handler((input, context) =>
|
|
831
|
-
const validation =
|
|
801
|
+
.handler(async (input, context) => {
|
|
802
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
832
803
|
if (validation.success === false) {
|
|
833
804
|
if (validation.errorCode === 'no_session_key') {
|
|
834
805
|
return NOT_LOGGED_IN_RESULT;
|
|
@@ -842,19 +813,19 @@ export class RecordsServer {
|
|
|
842
813
|
errorMessage: 'You are not authorized to perform this action.',
|
|
843
814
|
};
|
|
844
815
|
}
|
|
845
|
-
const result =
|
|
816
|
+
const result = await this._moderationController.scheduleModerationScans();
|
|
846
817
|
return result;
|
|
847
|
-
})
|
|
818
|
+
}),
|
|
848
819
|
eraseData: procedure()
|
|
849
820
|
.origins('api')
|
|
850
821
|
.http('DELETE', '/api/v2/records/data')
|
|
851
822
|
.inputs(ERASE_DATA_SCHEMA)
|
|
852
|
-
.handler((data, context) =>
|
|
823
|
+
.handler(async (data, context) => this._baseEraseRecordData(this._data, data, context)),
|
|
853
824
|
getData: procedure()
|
|
854
825
|
.origins(true)
|
|
855
826
|
.http('GET', '/api/v2/records/data')
|
|
856
827
|
.inputs(GET_DATA_SCHEMA)
|
|
857
|
-
.handler((data, context) =>
|
|
828
|
+
.handler(async (data, context) => this._baseGetRecordData(this._data, data, context)),
|
|
858
829
|
listData: procedure()
|
|
859
830
|
.origins(true)
|
|
860
831
|
.http('GET', '/api/v2/records/data/list')
|
|
@@ -865,7 +836,7 @@ export class RecordsServer {
|
|
|
865
836
|
sort: z.enum(['ascending', 'descending']).optional(),
|
|
866
837
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
867
838
|
}))
|
|
868
|
-
.handler(({ recordName, address, instances, marker, sort }, context) =>
|
|
839
|
+
.handler(async ({ recordName, address, instances, marker, sort }, context) => {
|
|
869
840
|
if (!recordName || typeof recordName !== 'string') {
|
|
870
841
|
return {
|
|
871
842
|
success: false,
|
|
@@ -882,17 +853,17 @@ export class RecordsServer {
|
|
|
882
853
|
errorMessage: 'address must be null or a string.',
|
|
883
854
|
};
|
|
884
855
|
}
|
|
885
|
-
const sessionKeyValidation =
|
|
856
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
886
857
|
if (sessionKeyValidation.success === false &&
|
|
887
858
|
sessionKeyValidation.errorCode !== 'no_session_key') {
|
|
888
859
|
return sessionKeyValidation;
|
|
889
860
|
}
|
|
890
861
|
if (!marker) {
|
|
891
|
-
const result =
|
|
862
|
+
const result = await this._data.listData(recordName, address || null, sessionKeyValidation.userId, instances);
|
|
892
863
|
return result;
|
|
893
864
|
}
|
|
894
865
|
else {
|
|
895
|
-
const result =
|
|
866
|
+
const result = await this._data.listDataByMarker({
|
|
896
867
|
recordKeyOrName: recordName,
|
|
897
868
|
marker: marker,
|
|
898
869
|
startingAddress: address,
|
|
@@ -902,12 +873,12 @@ export class RecordsServer {
|
|
|
902
873
|
});
|
|
903
874
|
return result;
|
|
904
875
|
}
|
|
905
|
-
})
|
|
876
|
+
}),
|
|
906
877
|
recordData: procedure()
|
|
907
878
|
.origins('api')
|
|
908
879
|
.http('POST', '/api/v2/records/data')
|
|
909
880
|
.inputs(RECORD_DATA_SCHEMA)
|
|
910
|
-
.handler((data, context) =>
|
|
881
|
+
.handler(async (data, context) => this._baseRecordData(this._data, data, context)),
|
|
911
882
|
recordWebhook: recordItemProcedure(this._auth, this._webhooksController, z.discriminatedUnion('targetResourceKind', [
|
|
912
883
|
z.object({
|
|
913
884
|
address: ADDRESS_VALIDATION,
|
|
@@ -946,8 +917,7 @@ export class RecordsServer {
|
|
|
946
917
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
947
918
|
})
|
|
948
919
|
.catchall(z.string()))
|
|
949
|
-
.handler((data, context,
|
|
950
|
-
var { recordName, address, instances } = _1, rest = __rest(_1, ["recordName", "address", "instances"]);
|
|
920
|
+
.handler(async (data, context, { recordName, address, instances, ...rest }) => {
|
|
951
921
|
if (!this._webhooksController) {
|
|
952
922
|
return {
|
|
953
923
|
success: false,
|
|
@@ -962,7 +932,7 @@ export class RecordsServer {
|
|
|
962
932
|
errorMessage: 'webhooks have to be called from an http request',
|
|
963
933
|
};
|
|
964
934
|
}
|
|
965
|
-
const validation =
|
|
935
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
966
936
|
if (validation.success === false &&
|
|
967
937
|
validation.errorCode !== 'no_session_key') {
|
|
968
938
|
return validation;
|
|
@@ -981,7 +951,7 @@ export class RecordsServer {
|
|
|
981
951
|
'connection',
|
|
982
952
|
'transfer-encoding',
|
|
983
953
|
];
|
|
984
|
-
const result =
|
|
954
|
+
const result = await this._webhooksController.handleWebhook({
|
|
985
955
|
recordName,
|
|
986
956
|
address,
|
|
987
957
|
instances,
|
|
@@ -1018,7 +988,7 @@ export class RecordsServer {
|
|
|
1018
988
|
body: result.response.body,
|
|
1019
989
|
},
|
|
1020
990
|
};
|
|
1021
|
-
}
|
|
991
|
+
}, async (output, context) => {
|
|
1022
992
|
if (output.success === false) {
|
|
1023
993
|
// Use defaults
|
|
1024
994
|
return {};
|
|
@@ -1026,7 +996,7 @@ export class RecordsServer {
|
|
|
1026
996
|
else if (output.success === true) {
|
|
1027
997
|
return output.response;
|
|
1028
998
|
}
|
|
1029
|
-
})
|
|
999
|
+
}),
|
|
1030
1000
|
eraseWebhook: eraseItemProcedure(this._auth, this._webhooksController, procedure()
|
|
1031
1001
|
.origins('api')
|
|
1032
1002
|
.http('DELETE', '/api/v2/records/webhook')),
|
|
@@ -1039,7 +1009,7 @@ export class RecordsServer {
|
|
|
1039
1009
|
requestTimeMs: z.number().int().optional(),
|
|
1040
1010
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1041
1011
|
}))
|
|
1042
|
-
.handler(({ recordName, address, requestTimeMs, instances }, context) =>
|
|
1012
|
+
.handler(async ({ recordName, address, requestTimeMs, instances }, context) => {
|
|
1043
1013
|
if (!this._webhooksController) {
|
|
1044
1014
|
return {
|
|
1045
1015
|
success: false,
|
|
@@ -1047,14 +1017,14 @@ export class RecordsServer {
|
|
|
1047
1017
|
errorMessage: 'This feature is not supported.',
|
|
1048
1018
|
};
|
|
1049
1019
|
}
|
|
1050
|
-
const validation =
|
|
1020
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1051
1021
|
if (validation.success === false) {
|
|
1052
1022
|
if (validation.errorCode === 'no_session_key') {
|
|
1053
1023
|
return NOT_LOGGED_IN_RESULT;
|
|
1054
1024
|
}
|
|
1055
1025
|
return validation;
|
|
1056
1026
|
}
|
|
1057
|
-
const result =
|
|
1027
|
+
const result = await this._webhooksController.listWebhookRuns({
|
|
1058
1028
|
recordName,
|
|
1059
1029
|
address,
|
|
1060
1030
|
userId: validation.userId,
|
|
@@ -1062,7 +1032,7 @@ export class RecordsServer {
|
|
|
1062
1032
|
instances,
|
|
1063
1033
|
});
|
|
1064
1034
|
return result;
|
|
1065
|
-
})
|
|
1035
|
+
}),
|
|
1066
1036
|
getWebhookRun: procedure()
|
|
1067
1037
|
.origins('api')
|
|
1068
1038
|
.http('GET', '/api/v2/records/webhook/runs/info')
|
|
@@ -1070,7 +1040,7 @@ export class RecordsServer {
|
|
|
1070
1040
|
runId: z.string().min(1),
|
|
1071
1041
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1072
1042
|
}))
|
|
1073
|
-
.handler(({ runId, instances }, context) =>
|
|
1043
|
+
.handler(async ({ runId, instances }, context) => {
|
|
1074
1044
|
if (!this._webhooksController) {
|
|
1075
1045
|
return {
|
|
1076
1046
|
success: false,
|
|
@@ -1078,20 +1048,20 @@ export class RecordsServer {
|
|
|
1078
1048
|
errorMessage: 'This feature is not supported.',
|
|
1079
1049
|
};
|
|
1080
1050
|
}
|
|
1081
|
-
const validation =
|
|
1051
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1082
1052
|
if (validation.success === false) {
|
|
1083
1053
|
if (validation.errorCode === 'no_session_key') {
|
|
1084
1054
|
return NOT_LOGGED_IN_RESULT;
|
|
1085
1055
|
}
|
|
1086
1056
|
return validation;
|
|
1087
1057
|
}
|
|
1088
|
-
const result =
|
|
1058
|
+
const result = await this._webhooksController.getWebhookRun({
|
|
1089
1059
|
runId,
|
|
1090
1060
|
userId: validation.userId,
|
|
1091
1061
|
instances,
|
|
1092
1062
|
});
|
|
1093
1063
|
return result;
|
|
1094
|
-
})
|
|
1064
|
+
}),
|
|
1095
1065
|
recordNotification: recordItemProcedure(this._auth, this._notificationsController, z.object({
|
|
1096
1066
|
address: ADDRESS_VALIDATION,
|
|
1097
1067
|
description: z.string().min(1),
|
|
@@ -1115,7 +1085,7 @@ export class RecordsServer {
|
|
|
1115
1085
|
address: ADDRESS_VALIDATION,
|
|
1116
1086
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1117
1087
|
}))
|
|
1118
|
-
.handler(({ recordName, address, instances }, context) =>
|
|
1088
|
+
.handler(async ({ recordName, address, instances }, context) => {
|
|
1119
1089
|
if (!this._notificationsController) {
|
|
1120
1090
|
return {
|
|
1121
1091
|
success: false,
|
|
@@ -1123,28 +1093,28 @@ export class RecordsServer {
|
|
|
1123
1093
|
errorMessage: 'This feature is not supported.',
|
|
1124
1094
|
};
|
|
1125
1095
|
}
|
|
1126
|
-
const validation =
|
|
1096
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1127
1097
|
if (validation.success === false) {
|
|
1128
1098
|
if (validation.errorCode === 'no_session_key') {
|
|
1129
1099
|
return NOT_LOGGED_IN_RESULT;
|
|
1130
1100
|
}
|
|
1131
1101
|
return validation;
|
|
1132
1102
|
}
|
|
1133
|
-
const result =
|
|
1103
|
+
const result = await this._notificationsController.listSubscriptions({
|
|
1134
1104
|
recordName,
|
|
1135
1105
|
address,
|
|
1136
1106
|
userId: validation.userId,
|
|
1137
1107
|
instances,
|
|
1138
1108
|
});
|
|
1139
1109
|
return result;
|
|
1140
|
-
})
|
|
1110
|
+
}),
|
|
1141
1111
|
listUserNotificationSubscriptions: procedure()
|
|
1142
1112
|
.origins('api')
|
|
1143
1113
|
.http('GET', '/api/v2/records/notification/list/user/subscriptions')
|
|
1144
1114
|
.inputs(z.object({
|
|
1145
1115
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1146
1116
|
}))
|
|
1147
|
-
.handler(({ instances }, context) =>
|
|
1117
|
+
.handler(async ({ instances }, context) => {
|
|
1148
1118
|
if (!this._notificationsController) {
|
|
1149
1119
|
return {
|
|
1150
1120
|
success: false,
|
|
@@ -1152,19 +1122,19 @@ export class RecordsServer {
|
|
|
1152
1122
|
errorMessage: 'This feature is not supported.',
|
|
1153
1123
|
};
|
|
1154
1124
|
}
|
|
1155
|
-
const validation =
|
|
1125
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1156
1126
|
if (validation.success === false) {
|
|
1157
1127
|
if (validation.errorCode === 'no_session_key') {
|
|
1158
1128
|
return NOT_LOGGED_IN_RESULT;
|
|
1159
1129
|
}
|
|
1160
1130
|
return validation;
|
|
1161
1131
|
}
|
|
1162
|
-
const result =
|
|
1132
|
+
const result = await this._notificationsController.listSubscriptionsForUser({
|
|
1163
1133
|
userId: validation.userId,
|
|
1164
1134
|
instances,
|
|
1165
1135
|
});
|
|
1166
1136
|
return result;
|
|
1167
|
-
})
|
|
1137
|
+
}),
|
|
1168
1138
|
eraseNotification: eraseItemProcedure(this._auth, this._notificationsController, procedure()
|
|
1169
1139
|
.origins('api')
|
|
1170
1140
|
.http('DELETE', '/api/v2/records/notification')),
|
|
@@ -1175,7 +1145,7 @@ export class RecordsServer {
|
|
|
1175
1145
|
pushSubscription: PUSH_SUBSCRIPTION_SCHEMA,
|
|
1176
1146
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1177
1147
|
}))
|
|
1178
|
-
.handler(({ pushSubscription, instances }, context) =>
|
|
1148
|
+
.handler(async ({ pushSubscription, instances }, context) => {
|
|
1179
1149
|
if (!this._notificationsController) {
|
|
1180
1150
|
return {
|
|
1181
1151
|
success: false,
|
|
@@ -1183,18 +1153,18 @@ export class RecordsServer {
|
|
|
1183
1153
|
errorMessage: 'This feature is not supported.',
|
|
1184
1154
|
};
|
|
1185
1155
|
}
|
|
1186
|
-
const validation =
|
|
1156
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1187
1157
|
if (validation.success === false &&
|
|
1188
1158
|
validation.errorCode !== 'no_session_key') {
|
|
1189
1159
|
return validation;
|
|
1190
1160
|
}
|
|
1191
|
-
const result =
|
|
1161
|
+
const result = await this._notificationsController.registerPushSubscription({
|
|
1192
1162
|
userId: validation.userId,
|
|
1193
1163
|
pushSubscription,
|
|
1194
1164
|
instances,
|
|
1195
1165
|
});
|
|
1196
1166
|
return result;
|
|
1197
|
-
})
|
|
1167
|
+
}),
|
|
1198
1168
|
subscribeToNotification: procedure()
|
|
1199
1169
|
.origins('api')
|
|
1200
1170
|
.http('POST', '/api/v2/records/notification/subscribe')
|
|
@@ -1204,7 +1174,7 @@ export class RecordsServer {
|
|
|
1204
1174
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1205
1175
|
pushSubscription: PUSH_SUBSCRIPTION_SCHEMA,
|
|
1206
1176
|
}))
|
|
1207
|
-
.handler(({ recordName, address, instances, pushSubscription }, context) =>
|
|
1177
|
+
.handler(async ({ recordName, address, instances, pushSubscription }, context) => {
|
|
1208
1178
|
if (!this._notificationsController) {
|
|
1209
1179
|
return {
|
|
1210
1180
|
success: false,
|
|
@@ -1212,12 +1182,12 @@ export class RecordsServer {
|
|
|
1212
1182
|
errorMessage: 'This feature is not supported.',
|
|
1213
1183
|
};
|
|
1214
1184
|
}
|
|
1215
|
-
const validation =
|
|
1185
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1216
1186
|
if (validation.success === false &&
|
|
1217
1187
|
validation.errorCode !== 'no_session_key') {
|
|
1218
1188
|
return validation;
|
|
1219
1189
|
}
|
|
1220
|
-
const result =
|
|
1190
|
+
const result = await this._notificationsController.subscribeToNotification({
|
|
1221
1191
|
recordName,
|
|
1222
1192
|
address,
|
|
1223
1193
|
userId: validation.userId,
|
|
@@ -1225,7 +1195,7 @@ export class RecordsServer {
|
|
|
1225
1195
|
instances,
|
|
1226
1196
|
});
|
|
1227
1197
|
return result;
|
|
1228
|
-
})
|
|
1198
|
+
}),
|
|
1229
1199
|
unsubscribeFromNotification: procedure()
|
|
1230
1200
|
.origins('api')
|
|
1231
1201
|
.http('POST', '/api/v2/records/notification/unsubscribe')
|
|
@@ -1233,7 +1203,7 @@ export class RecordsServer {
|
|
|
1233
1203
|
subscriptionId: z.string(),
|
|
1234
1204
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1235
1205
|
}))
|
|
1236
|
-
.handler(({ subscriptionId, instances }, context) =>
|
|
1206
|
+
.handler(async ({ subscriptionId, instances }, context) => {
|
|
1237
1207
|
if (!this._notificationsController) {
|
|
1238
1208
|
return {
|
|
1239
1209
|
success: false,
|
|
@@ -1241,20 +1211,20 @@ export class RecordsServer {
|
|
|
1241
1211
|
errorMessage: 'This feature is not supported.',
|
|
1242
1212
|
};
|
|
1243
1213
|
}
|
|
1244
|
-
const validation =
|
|
1214
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1245
1215
|
if (validation.success === false) {
|
|
1246
1216
|
if (validation.errorCode === 'no_session_key') {
|
|
1247
1217
|
return NOT_LOGGED_IN_RESULT;
|
|
1248
1218
|
}
|
|
1249
1219
|
return validation;
|
|
1250
1220
|
}
|
|
1251
|
-
const result =
|
|
1221
|
+
const result = await this._notificationsController.unsubscribeFromNotification({
|
|
1252
1222
|
subscriptionId,
|
|
1253
1223
|
userId: validation.userId,
|
|
1254
1224
|
instances,
|
|
1255
1225
|
});
|
|
1256
1226
|
return result;
|
|
1257
|
-
})
|
|
1227
|
+
}),
|
|
1258
1228
|
sendNotification: procedure()
|
|
1259
1229
|
.origins('api')
|
|
1260
1230
|
.http('POST', '/api/v2/records/notification/send')
|
|
@@ -1265,7 +1235,7 @@ export class RecordsServer {
|
|
|
1265
1235
|
payload: PUSH_NOTIFICATION_PAYLOAD,
|
|
1266
1236
|
topic: z.string().optional(),
|
|
1267
1237
|
}))
|
|
1268
|
-
.handler(({ recordName, address, instances, payload, topic }, context) =>
|
|
1238
|
+
.handler(async ({ recordName, address, instances, payload, topic }, context) => {
|
|
1269
1239
|
if (!this._notificationsController) {
|
|
1270
1240
|
return {
|
|
1271
1241
|
success: false,
|
|
@@ -1273,14 +1243,14 @@ export class RecordsServer {
|
|
|
1273
1243
|
errorMessage: 'This feature is not supported.',
|
|
1274
1244
|
};
|
|
1275
1245
|
}
|
|
1276
|
-
const validation =
|
|
1246
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1277
1247
|
if (validation.success === false) {
|
|
1278
1248
|
if (validation.errorCode === 'no_session_key') {
|
|
1279
1249
|
return NOT_LOGGED_IN_RESULT;
|
|
1280
1250
|
}
|
|
1281
1251
|
return validation;
|
|
1282
1252
|
}
|
|
1283
|
-
const result =
|
|
1253
|
+
const result = await this._notificationsController.sendNotification({
|
|
1284
1254
|
recordName,
|
|
1285
1255
|
address,
|
|
1286
1256
|
userId: validation.userId,
|
|
@@ -1289,11 +1259,11 @@ export class RecordsServer {
|
|
|
1289
1259
|
instances,
|
|
1290
1260
|
});
|
|
1291
1261
|
return result;
|
|
1292
|
-
})
|
|
1262
|
+
}),
|
|
1293
1263
|
getNotificationsApplicationServerKey: procedure()
|
|
1294
1264
|
.origins('api')
|
|
1295
1265
|
.http('GET', '/api/v2/records/notification/applicationServerKey')
|
|
1296
|
-
.handler(() =>
|
|
1266
|
+
.handler(async () => {
|
|
1297
1267
|
if (!this._notificationsController) {
|
|
1298
1268
|
return {
|
|
1299
1269
|
success: false,
|
|
@@ -1301,158 +1271,487 @@ export class RecordsServer {
|
|
|
1301
1271
|
errorMessage: 'This feature is not supported.',
|
|
1302
1272
|
};
|
|
1303
1273
|
}
|
|
1304
|
-
const result =
|
|
1274
|
+
const result = await this._notificationsController.getApplicationServerKey();
|
|
1305
1275
|
return result;
|
|
1306
|
-
})
|
|
1307
|
-
|
|
1276
|
+
}),
|
|
1277
|
+
getPackage: getItemProcedure(this._auth, this._packagesController, procedure()
|
|
1308
1278
|
.origins('api')
|
|
1309
|
-
.http('GET', '/api/v2/records/
|
|
1279
|
+
.http('GET', '/api/v2/records/package')),
|
|
1280
|
+
recordPackage: recordItemProcedure(this._auth, this._packagesController, z.object({
|
|
1281
|
+
address: ADDRESS_VALIDATION,
|
|
1282
|
+
markers: MARKERS_VALIDATION,
|
|
1283
|
+
}), procedure()
|
|
1284
|
+
.origins('api')
|
|
1285
|
+
.http('POST', '/api/v2/records/package')),
|
|
1286
|
+
erasePackage: eraseItemProcedure(this._auth, this._packagesController, procedure()
|
|
1287
|
+
.origins('api')
|
|
1288
|
+
.http('DELETE', '/api/v2/records/package')),
|
|
1289
|
+
listPackages: listItemsProcedure(this._auth, this._packagesController, procedure()
|
|
1290
|
+
.origins('api')
|
|
1291
|
+
.http('GET', '/api/v2/records/package/list')),
|
|
1292
|
+
getPackageVersion: procedure()
|
|
1293
|
+
.origins('api')
|
|
1294
|
+
.http('GET', '/api/v2/records/package/version')
|
|
1310
1295
|
.inputs(z.object({
|
|
1311
|
-
|
|
1312
|
-
|
|
1296
|
+
recordName: RECORD_NAME_VALIDATION,
|
|
1297
|
+
address: ADDRESS_VALIDATION,
|
|
1298
|
+
major: z.coerce.number().int().optional().nullable(),
|
|
1299
|
+
minor: z.coerce.number().int().optional().nullable(),
|
|
1300
|
+
patch: z.coerce.number().int().optional().nullable(),
|
|
1301
|
+
tag: z.string().optional().nullable(),
|
|
1302
|
+
sha256: z.string().optional(),
|
|
1303
|
+
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1304
|
+
key: z.string().min(1).optional(),
|
|
1313
1305
|
}))
|
|
1314
|
-
.handler(({
|
|
1315
|
-
|
|
1306
|
+
.handler(async ({ recordName, address, major, minor, patch, tag, sha256, key, instances, }, context) => {
|
|
1307
|
+
if (!this._packageVersionController) {
|
|
1308
|
+
return {
|
|
1309
|
+
success: false,
|
|
1310
|
+
errorCode: 'not_supported',
|
|
1311
|
+
errorMessage: 'This feature is not supported.',
|
|
1312
|
+
};
|
|
1313
|
+
}
|
|
1314
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1316
1315
|
if (validation.success === false) {
|
|
1317
1316
|
if (validation.errorCode === 'no_session_key') {
|
|
1318
1317
|
return NOT_LOGGED_IN_RESULT;
|
|
1319
1318
|
}
|
|
1320
1319
|
return validation;
|
|
1321
1320
|
}
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
return
|
|
1325
|
-
}
|
|
1326
|
-
else if (userId && userId !== validation.userId) {
|
|
1327
|
-
if (!isSuperUserRole(validation.role)) {
|
|
1328
|
-
return {
|
|
1329
|
-
success: false,
|
|
1330
|
-
errorCode: 'not_authorized',
|
|
1331
|
-
errorMessage: 'You are not authorized to perform this action.',
|
|
1332
|
-
};
|
|
1333
|
-
}
|
|
1334
|
-
const result = yield this._records.listRecords(userId);
|
|
1335
|
-
return result;
|
|
1336
|
-
}
|
|
1337
|
-
else {
|
|
1338
|
-
const result = yield this._records.listRecords(validation.userId);
|
|
1339
|
-
return result;
|
|
1321
|
+
const keyResult = getPackageVersionSpecifier(key, major, minor, patch, tag, sha256);
|
|
1322
|
+
if (keyResult.success === false) {
|
|
1323
|
+
return keyResult;
|
|
1340
1324
|
}
|
|
1341
|
-
|
|
1342
|
-
|
|
1325
|
+
const result = await this._packageVersionController.getItem({
|
|
1326
|
+
recordName,
|
|
1327
|
+
address,
|
|
1328
|
+
userId: validation.userId,
|
|
1329
|
+
key: keyResult.key,
|
|
1330
|
+
instances,
|
|
1331
|
+
});
|
|
1332
|
+
return result;
|
|
1333
|
+
}),
|
|
1334
|
+
recordPackageVersion: procedure()
|
|
1343
1335
|
.origins('api')
|
|
1344
|
-
.http('POST', '/api/v2/records/
|
|
1336
|
+
.http('POST', '/api/v2/records/package/version')
|
|
1345
1337
|
.inputs(z.object({
|
|
1346
1338
|
recordName: RECORD_NAME_VALIDATION,
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1339
|
+
item: z.object({
|
|
1340
|
+
address: ADDRESS_VALIDATION,
|
|
1341
|
+
key: z.object({
|
|
1342
|
+
major: z.number().int(),
|
|
1343
|
+
minor: z.number().int(),
|
|
1344
|
+
patch: z.number().int(),
|
|
1345
|
+
tag: z
|
|
1346
|
+
.string()
|
|
1347
|
+
.max(16)
|
|
1348
|
+
.nullable()
|
|
1349
|
+
.optional()
|
|
1350
|
+
.default(''),
|
|
1351
|
+
}),
|
|
1352
|
+
auxFileRequest: z.object({
|
|
1353
|
+
fileSha256Hex: z.string().min(1).max(123),
|
|
1354
|
+
fileByteLength: z.number().positive().int(),
|
|
1355
|
+
fileMimeType: z.string().min(1).max(128),
|
|
1356
|
+
fileDescription: z
|
|
1357
|
+
.string()
|
|
1358
|
+
.min(1)
|
|
1359
|
+
.max(128)
|
|
1360
|
+
.optional(),
|
|
1361
|
+
}),
|
|
1362
|
+
entitlements: z.array(ENTITLEMENT_VALIDATION),
|
|
1363
|
+
description: z.string(),
|
|
1364
|
+
markers: MARKERS_VALIDATION.optional(),
|
|
1350
1365
|
}),
|
|
1366
|
+
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1351
1367
|
}))
|
|
1352
|
-
.handler(({ recordName,
|
|
1353
|
-
|
|
1368
|
+
.handler(async ({ recordName, item, instances }, context) => {
|
|
1369
|
+
var _a;
|
|
1370
|
+
if (!this._packageVersionController) {
|
|
1354
1371
|
return {
|
|
1355
1372
|
success: false,
|
|
1356
|
-
errorCode: '
|
|
1357
|
-
errorMessage: '
|
|
1373
|
+
errorCode: 'not_supported',
|
|
1374
|
+
errorMessage: 'This feature is not supported.',
|
|
1358
1375
|
};
|
|
1359
1376
|
}
|
|
1360
|
-
const validation =
|
|
1377
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1361
1378
|
if (validation.success === false) {
|
|
1362
1379
|
if (validation.errorCode === 'no_session_key') {
|
|
1363
1380
|
return NOT_LOGGED_IN_RESULT;
|
|
1364
1381
|
}
|
|
1365
1382
|
return validation;
|
|
1366
1383
|
}
|
|
1367
|
-
const result =
|
|
1384
|
+
const result = await this._packageVersionController.recordItem({
|
|
1385
|
+
recordKeyOrRecordName: recordName,
|
|
1386
|
+
userId: validation.userId,
|
|
1387
|
+
item: {
|
|
1388
|
+
address: item.address,
|
|
1389
|
+
key: {
|
|
1390
|
+
major: item.key.major,
|
|
1391
|
+
minor: item.key.minor,
|
|
1392
|
+
patch: item.key.patch,
|
|
1393
|
+
tag: (_a = item.key.tag) !== null && _a !== void 0 ? _a : '',
|
|
1394
|
+
},
|
|
1395
|
+
auxFileRequest: item.auxFileRequest,
|
|
1396
|
+
entitlements: item.entitlements,
|
|
1397
|
+
description: item.description,
|
|
1398
|
+
markers: item.markers,
|
|
1399
|
+
},
|
|
1400
|
+
instances,
|
|
1401
|
+
});
|
|
1368
1402
|
return result;
|
|
1369
|
-
})
|
|
1370
|
-
|
|
1403
|
+
}),
|
|
1404
|
+
listPackageVersions: procedure()
|
|
1371
1405
|
.origins('api')
|
|
1372
|
-
.http('
|
|
1406
|
+
.http('GET', '/api/v2/records/package/version/list')
|
|
1373
1407
|
.inputs(z.object({
|
|
1374
1408
|
recordName: RECORD_NAME_VALIDATION,
|
|
1375
|
-
|
|
1409
|
+
address: ADDRESS_VALIDATION,
|
|
1376
1410
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1377
1411
|
}))
|
|
1378
|
-
.handler(({ recordName,
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
'
|
|
1383
|
-
|
|
1384
|
-
}
|
|
1385
|
-
return sessionKeyValidation;
|
|
1386
|
-
}
|
|
1387
|
-
if (permission.marker) {
|
|
1388
|
-
const result = yield this._policyController.grantMarkerPermission({
|
|
1389
|
-
recordKeyOrRecordName: recordName,
|
|
1390
|
-
marker: permission.marker,
|
|
1391
|
-
userId: sessionKeyValidation.userId,
|
|
1392
|
-
permission: permission,
|
|
1393
|
-
instances,
|
|
1394
|
-
});
|
|
1395
|
-
return result;
|
|
1412
|
+
.handler(async ({ recordName, address, instances }, context) => {
|
|
1413
|
+
if (!this._packageVersionController) {
|
|
1414
|
+
return {
|
|
1415
|
+
success: false,
|
|
1416
|
+
errorCode: 'not_supported',
|
|
1417
|
+
errorMessage: 'This feature is not supported.',
|
|
1418
|
+
};
|
|
1396
1419
|
}
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
permission: permission,
|
|
1402
|
-
userId: sessionKeyValidation.userId,
|
|
1403
|
-
instances,
|
|
1404
|
-
});
|
|
1405
|
-
return result;
|
|
1420
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1421
|
+
if (validation.success === false &&
|
|
1422
|
+
validation.errorCode !== 'no_session_key') {
|
|
1423
|
+
return validation;
|
|
1406
1424
|
}
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1425
|
+
const result = await this._packageVersionController.listItems({
|
|
1426
|
+
userId: validation.userId,
|
|
1427
|
+
recordName: recordName,
|
|
1428
|
+
address: address,
|
|
1429
|
+
instances: instances !== null && instances !== void 0 ? instances : [],
|
|
1430
|
+
});
|
|
1431
|
+
return result;
|
|
1432
|
+
}),
|
|
1433
|
+
erasePackageVersion: procedure()
|
|
1414
1434
|
.origins('api')
|
|
1415
|
-
.http('
|
|
1435
|
+
.http('DELETE', '/api/v2/records/package/version')
|
|
1416
1436
|
.inputs(z.object({
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
.
|
|
1437
|
+
recordName: RECORD_NAME_VALIDATION,
|
|
1438
|
+
address: ADDRESS_VALIDATION,
|
|
1439
|
+
key: z.object({
|
|
1440
|
+
major: z.number().int(),
|
|
1441
|
+
minor: z.number().int(),
|
|
1442
|
+
patch: z.number().int(),
|
|
1443
|
+
tag: z.string().max(16).default(''),
|
|
1444
|
+
}),
|
|
1423
1445
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1424
1446
|
}))
|
|
1425
|
-
.handler(({
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1447
|
+
.handler(async ({ recordName, address, key, instances }, context) => {
|
|
1448
|
+
if (!this._packageVersionController) {
|
|
1449
|
+
return {
|
|
1450
|
+
success: false,
|
|
1451
|
+
errorCode: 'not_supported',
|
|
1452
|
+
errorMessage: 'This feature is not supported.',
|
|
1453
|
+
};
|
|
1454
|
+
}
|
|
1455
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1456
|
+
if (validation.success === false) {
|
|
1457
|
+
if (validation.errorCode === 'no_session_key') {
|
|
1429
1458
|
return NOT_LOGGED_IN_RESULT;
|
|
1430
1459
|
}
|
|
1431
|
-
return
|
|
1460
|
+
return validation;
|
|
1432
1461
|
}
|
|
1433
|
-
const result =
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1462
|
+
const result = await this._packageVersionController.eraseItem({
|
|
1463
|
+
recordName,
|
|
1464
|
+
address,
|
|
1465
|
+
key: key,
|
|
1466
|
+
userId: validation.userId,
|
|
1467
|
+
instances: instances !== null && instances !== void 0 ? instances : [],
|
|
1437
1468
|
});
|
|
1438
1469
|
return result;
|
|
1439
|
-
})
|
|
1440
|
-
|
|
1470
|
+
}),
|
|
1471
|
+
reviewPackageVersion: procedure()
|
|
1441
1472
|
.origins('api')
|
|
1442
|
-
.http('
|
|
1473
|
+
.http('POST', '/api/v2/records/package/version/review')
|
|
1443
1474
|
.inputs(z.object({
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1475
|
+
packageVersionId: z.string().min(1).max(36),
|
|
1476
|
+
review: z.object({
|
|
1477
|
+
id: z.string().min(1).max(36).optional(),
|
|
1478
|
+
approved: z.boolean(),
|
|
1479
|
+
approvalType: z
|
|
1480
|
+
.enum(['normal', 'super'])
|
|
1481
|
+
.nullable(),
|
|
1482
|
+
reviewStatus: z.enum([
|
|
1483
|
+
'pending',
|
|
1484
|
+
'approved',
|
|
1485
|
+
'rejected',
|
|
1486
|
+
]),
|
|
1487
|
+
reviewComments: z.string().min(1).max(4096),
|
|
1488
|
+
}),
|
|
1489
|
+
}))
|
|
1490
|
+
.handler(async ({ packageVersionId, review }, context) => {
|
|
1491
|
+
if (!this._packageVersionController) {
|
|
1492
|
+
return {
|
|
1493
|
+
success: false,
|
|
1494
|
+
errorCode: 'not_supported',
|
|
1495
|
+
errorMessage: 'This feature is not supported.',
|
|
1496
|
+
};
|
|
1497
|
+
}
|
|
1498
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1499
|
+
if (validation.success === false) {
|
|
1500
|
+
if (validation.errorCode === 'no_session_key') {
|
|
1501
|
+
return NOT_LOGGED_IN_RESULT;
|
|
1502
|
+
}
|
|
1503
|
+
return validation;
|
|
1504
|
+
}
|
|
1505
|
+
const result = await this._packageVersionController.reviewItem({
|
|
1506
|
+
packageVersionId,
|
|
1507
|
+
userId: validation.userId,
|
|
1508
|
+
review: review,
|
|
1509
|
+
});
|
|
1510
|
+
return result;
|
|
1511
|
+
}),
|
|
1512
|
+
installPackage: procedure()
|
|
1513
|
+
.origins('api')
|
|
1514
|
+
.http('POST', '/api/v2/records/package/install')
|
|
1515
|
+
.inputs(z.object({
|
|
1516
|
+
recordName: RECORD_NAME_VALIDATION.optional().nullable(),
|
|
1517
|
+
inst: z.string().min(1),
|
|
1518
|
+
branch: z.string().optional().nullable(),
|
|
1519
|
+
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1520
|
+
package: z.object({
|
|
1521
|
+
recordName: RECORD_NAME_VALIDATION,
|
|
1522
|
+
address: ADDRESS_VALIDATION,
|
|
1523
|
+
key: z
|
|
1524
|
+
.union([
|
|
1525
|
+
z
|
|
1526
|
+
.string()
|
|
1527
|
+
.describe('The package version to install as a string'),
|
|
1528
|
+
z
|
|
1529
|
+
.object({
|
|
1530
|
+
major: z
|
|
1531
|
+
.number()
|
|
1532
|
+
.int()
|
|
1533
|
+
.optional()
|
|
1534
|
+
.nullable(),
|
|
1535
|
+
minor: z
|
|
1536
|
+
.number()
|
|
1537
|
+
.int()
|
|
1538
|
+
.optional()
|
|
1539
|
+
.nullable(),
|
|
1540
|
+
patch: z
|
|
1541
|
+
.number()
|
|
1542
|
+
.int()
|
|
1543
|
+
.optional()
|
|
1544
|
+
.nullable(),
|
|
1545
|
+
tag: z
|
|
1546
|
+
.string()
|
|
1547
|
+
.optional()
|
|
1548
|
+
.nullable(),
|
|
1549
|
+
sha256: z
|
|
1550
|
+
.string()
|
|
1551
|
+
.optional()
|
|
1552
|
+
.nullable(),
|
|
1553
|
+
})
|
|
1554
|
+
.describe('The package version specifier to install'),
|
|
1555
|
+
])
|
|
1556
|
+
.optional()
|
|
1557
|
+
.nullable(),
|
|
1558
|
+
}),
|
|
1559
|
+
}))
|
|
1560
|
+
.handler(async ({ recordName, inst, branch, package: pkg, instances }, context) => {
|
|
1561
|
+
if (!this._websocketController) {
|
|
1562
|
+
return INSTS_NOT_SUPPORTED_RESULT;
|
|
1563
|
+
}
|
|
1564
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1565
|
+
if (validation.success === false &&
|
|
1566
|
+
validation.errorCode !== 'no_session_key') {
|
|
1567
|
+
return validation;
|
|
1568
|
+
}
|
|
1569
|
+
const result = await this._websocketController.installPackage({
|
|
1570
|
+
userId: validation.userId,
|
|
1571
|
+
userRole: validation.role,
|
|
1572
|
+
recordName: recordName !== null && recordName !== void 0 ? recordName : null,
|
|
1573
|
+
inst,
|
|
1574
|
+
branch,
|
|
1575
|
+
package: pkg,
|
|
1576
|
+
instances,
|
|
1577
|
+
});
|
|
1578
|
+
return result;
|
|
1579
|
+
}),
|
|
1580
|
+
listInstalledPackages: procedure()
|
|
1581
|
+
.origins('api')
|
|
1582
|
+
.http('GET', '/api/v2/records/package/install/list')
|
|
1583
|
+
.inputs(z.object({
|
|
1584
|
+
recordName: RECORD_NAME_VALIDATION.optional().nullable(),
|
|
1585
|
+
inst: z.string().min(1),
|
|
1586
|
+
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1587
|
+
}))
|
|
1588
|
+
.handler(async ({ recordName, inst, instances }, context) => {
|
|
1589
|
+
if (!this._websocketController) {
|
|
1590
|
+
return INSTS_NOT_SUPPORTED_RESULT;
|
|
1591
|
+
}
|
|
1592
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1593
|
+
if (validation.success === false &&
|
|
1594
|
+
validation.errorCode !== 'no_session_key') {
|
|
1595
|
+
return validation;
|
|
1596
|
+
}
|
|
1597
|
+
const result = await this._websocketController.listInstalledPackages({
|
|
1598
|
+
userId: validation.userId,
|
|
1599
|
+
userRole: validation.role,
|
|
1600
|
+
recordName: recordName !== null && recordName !== void 0 ? recordName : null,
|
|
1601
|
+
inst,
|
|
1602
|
+
instances,
|
|
1603
|
+
});
|
|
1604
|
+
return result;
|
|
1605
|
+
}),
|
|
1606
|
+
listRecords: procedure()
|
|
1607
|
+
.origins('api')
|
|
1608
|
+
.http('GET', '/api/v2/records/list')
|
|
1609
|
+
.inputs(z.object({
|
|
1610
|
+
studioId: z.string().nonempty().optional(),
|
|
1611
|
+
userId: z.string().optional(),
|
|
1612
|
+
}))
|
|
1613
|
+
.handler(async ({ studioId, userId }, context) => {
|
|
1614
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1615
|
+
if (validation.success === false) {
|
|
1616
|
+
if (validation.errorCode === 'no_session_key') {
|
|
1617
|
+
return NOT_LOGGED_IN_RESULT;
|
|
1618
|
+
}
|
|
1619
|
+
return validation;
|
|
1620
|
+
}
|
|
1621
|
+
if (studioId) {
|
|
1622
|
+
const result = await this._records.listStudioRecords(studioId, validation.userId);
|
|
1623
|
+
return result;
|
|
1624
|
+
}
|
|
1625
|
+
else if (userId && userId !== validation.userId) {
|
|
1626
|
+
if (!isSuperUserRole(validation.role)) {
|
|
1627
|
+
return {
|
|
1628
|
+
success: false,
|
|
1629
|
+
errorCode: 'not_authorized',
|
|
1630
|
+
errorMessage: 'You are not authorized to perform this action.',
|
|
1631
|
+
};
|
|
1632
|
+
}
|
|
1633
|
+
const result = await this._records.listRecords(userId);
|
|
1634
|
+
return result;
|
|
1635
|
+
}
|
|
1636
|
+
else {
|
|
1637
|
+
const result = await this._records.listRecords(validation.userId);
|
|
1638
|
+
return result;
|
|
1639
|
+
}
|
|
1640
|
+
}),
|
|
1641
|
+
createRecordKey: procedure()
|
|
1642
|
+
.origins('api')
|
|
1643
|
+
.http('POST', '/api/v2/records/key')
|
|
1644
|
+
.inputs(z.object({
|
|
1645
|
+
recordName: RECORD_NAME_VALIDATION,
|
|
1646
|
+
policy: z.string({
|
|
1647
|
+
invalid_type_error: 'policy must be a string.',
|
|
1648
|
+
required_error: 'policy is required.',
|
|
1649
|
+
}),
|
|
1650
|
+
}))
|
|
1651
|
+
.handler(async ({ recordName, policy }, context) => {
|
|
1652
|
+
if (!recordName || typeof recordName !== 'string') {
|
|
1653
|
+
return {
|
|
1654
|
+
success: false,
|
|
1655
|
+
errorCode: 'unacceptable_request',
|
|
1656
|
+
errorMessage: 'recordName is required and must be a string.',
|
|
1657
|
+
};
|
|
1658
|
+
}
|
|
1659
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
1660
|
+
if (validation.success === false) {
|
|
1661
|
+
if (validation.errorCode === 'no_session_key') {
|
|
1662
|
+
return NOT_LOGGED_IN_RESULT;
|
|
1663
|
+
}
|
|
1664
|
+
return validation;
|
|
1665
|
+
}
|
|
1666
|
+
const result = await this._records.createPublicRecordKey(recordName, policy, validation.userId);
|
|
1667
|
+
return result;
|
|
1668
|
+
}),
|
|
1669
|
+
grantPermission: procedure()
|
|
1670
|
+
.origins('api')
|
|
1671
|
+
.http('POST', '/api/v2/records/permissions')
|
|
1672
|
+
.inputs(z.object({
|
|
1673
|
+
recordName: RECORD_NAME_VALIDATION,
|
|
1674
|
+
permission: AVAILABLE_PERMISSIONS_VALIDATION,
|
|
1675
|
+
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1676
|
+
}))
|
|
1677
|
+
.handler(async ({ recordName, permission, instances }, context) => {
|
|
1678
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
1679
|
+
if (sessionKeyValidation.success === false) {
|
|
1680
|
+
if (sessionKeyValidation.errorCode ===
|
|
1681
|
+
'no_session_key') {
|
|
1682
|
+
return NOT_LOGGED_IN_RESULT;
|
|
1683
|
+
}
|
|
1684
|
+
return sessionKeyValidation;
|
|
1685
|
+
}
|
|
1686
|
+
if (permission.marker) {
|
|
1687
|
+
const result = await this._policyController.grantMarkerPermission({
|
|
1688
|
+
recordKeyOrRecordName: recordName,
|
|
1689
|
+
marker: permission.marker,
|
|
1690
|
+
userId: sessionKeyValidation.userId,
|
|
1691
|
+
permission: permission,
|
|
1692
|
+
instances,
|
|
1693
|
+
});
|
|
1694
|
+
return result;
|
|
1695
|
+
}
|
|
1696
|
+
else if (permission.resourceKind &&
|
|
1697
|
+
permission.resourceId) {
|
|
1698
|
+
const result = await this._policyController.grantResourcePermission({
|
|
1699
|
+
recordKeyOrRecordName: recordName,
|
|
1700
|
+
permission: permission,
|
|
1701
|
+
userId: sessionKeyValidation.userId,
|
|
1702
|
+
instances,
|
|
1703
|
+
});
|
|
1704
|
+
return result;
|
|
1705
|
+
}
|
|
1706
|
+
return {
|
|
1707
|
+
success: false,
|
|
1708
|
+
errorCode: 'unacceptable_request',
|
|
1709
|
+
errorMessage: 'The given permission must have either a marker or a resourceId.',
|
|
1710
|
+
};
|
|
1711
|
+
}),
|
|
1712
|
+
revokePermission: procedure()
|
|
1713
|
+
.origins('api')
|
|
1714
|
+
.http('POST', '/api/v2/records/permissions/revoke')
|
|
1715
|
+
.inputs(z.object({
|
|
1716
|
+
permissionId: z
|
|
1717
|
+
.string({
|
|
1718
|
+
invalid_type_error: 'permissionId must be a string.',
|
|
1719
|
+
required_error: 'permissionId is required.',
|
|
1720
|
+
})
|
|
1721
|
+
.nonempty('permissionId must not be empty'),
|
|
1722
|
+
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1723
|
+
}))
|
|
1724
|
+
.handler(async ({ permissionId, instances }, context) => {
|
|
1725
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
1726
|
+
if (sessionKeyValidation.success === false) {
|
|
1727
|
+
if (sessionKeyValidation.errorCode === 'no_session_key') {
|
|
1728
|
+
return NOT_LOGGED_IN_RESULT;
|
|
1729
|
+
}
|
|
1730
|
+
return sessionKeyValidation;
|
|
1731
|
+
}
|
|
1732
|
+
const result = await this._policyController.revokePermission({
|
|
1733
|
+
permissionId,
|
|
1734
|
+
userId: sessionKeyValidation.userId,
|
|
1735
|
+
instances,
|
|
1736
|
+
});
|
|
1737
|
+
return result;
|
|
1738
|
+
}),
|
|
1739
|
+
listPermissions: procedure()
|
|
1740
|
+
.origins('api')
|
|
1741
|
+
.http('GET', '/api/v2/records/permissions/list')
|
|
1742
|
+
.inputs(z.object({
|
|
1743
|
+
recordName: RECORD_NAME_VALIDATION,
|
|
1744
|
+
marker: MARKER_VALIDATION.optional(),
|
|
1745
|
+
resourceKind: RESOURCE_KIND_VALIDATION.optional(),
|
|
1746
|
+
resourceId: z
|
|
1747
|
+
.string({
|
|
1748
|
+
invalid_type_error: 'resourceId must be a string.',
|
|
1749
|
+
required_error: 'resourceId is required.',
|
|
1750
|
+
})
|
|
1751
|
+
.optional(),
|
|
1453
1752
|
}))
|
|
1454
|
-
.handler(({ recordName, marker, resourceKind, resourceId }, context) =>
|
|
1455
|
-
const sessionKeyValidation =
|
|
1753
|
+
.handler(async ({ recordName, marker, resourceKind, resourceId }, context) => {
|
|
1754
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
1456
1755
|
if (sessionKeyValidation.success === false) {
|
|
1457
1756
|
if (sessionKeyValidation.errorCode ===
|
|
1458
1757
|
'no_session_key') {
|
|
@@ -1461,18 +1760,18 @@ export class RecordsServer {
|
|
|
1461
1760
|
return sessionKeyValidation;
|
|
1462
1761
|
}
|
|
1463
1762
|
if (resourceKind && resourceId) {
|
|
1464
|
-
const result =
|
|
1763
|
+
const result = await this._policyController.listPermissionsForResource(recordName, resourceKind, resourceId, sessionKeyValidation.userId);
|
|
1465
1764
|
return result;
|
|
1466
1765
|
}
|
|
1467
1766
|
else if (marker) {
|
|
1468
|
-
const result =
|
|
1767
|
+
const result = await this._policyController.listPermissionsForMarker(recordName, marker, sessionKeyValidation.userId);
|
|
1469
1768
|
return result;
|
|
1470
1769
|
}
|
|
1471
1770
|
else {
|
|
1472
|
-
const result =
|
|
1771
|
+
const result = await this._policyController.listPermissions(recordName, sessionKeyValidation.userId);
|
|
1473
1772
|
return result;
|
|
1474
1773
|
}
|
|
1475
|
-
})
|
|
1774
|
+
}),
|
|
1476
1775
|
listUserRoles: procedure()
|
|
1477
1776
|
.origins('api')
|
|
1478
1777
|
.http('GET', '/api/v2/records/role/user/list')
|
|
@@ -1486,17 +1785,17 @@ export class RecordsServer {
|
|
|
1486
1785
|
.nonempty('userId must not be empty'),
|
|
1487
1786
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1488
1787
|
}))
|
|
1489
|
-
.handler(({ recordName, userId, instances }, context) =>
|
|
1490
|
-
const sessionKeyValidation =
|
|
1788
|
+
.handler(async ({ recordName, userId, instances }, context) => {
|
|
1789
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
1491
1790
|
if (sessionKeyValidation.success === false) {
|
|
1492
1791
|
if (sessionKeyValidation.errorCode === 'no_session_key') {
|
|
1493
1792
|
return NOT_LOGGED_IN_RESULT;
|
|
1494
1793
|
}
|
|
1495
1794
|
return sessionKeyValidation;
|
|
1496
1795
|
}
|
|
1497
|
-
const result =
|
|
1796
|
+
const result = await this._policyController.listUserRoles(recordName, sessionKeyValidation.userId, userId, instances);
|
|
1498
1797
|
return result;
|
|
1499
|
-
})
|
|
1798
|
+
}),
|
|
1500
1799
|
listInstRoles: procedure()
|
|
1501
1800
|
.origins('api')
|
|
1502
1801
|
.http('GET', '/api/v2/records/role/inst/list')
|
|
@@ -1510,17 +1809,17 @@ export class RecordsServer {
|
|
|
1510
1809
|
.nonempty('inst must not be empty'),
|
|
1511
1810
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1512
1811
|
}))
|
|
1513
|
-
.handler(({ recordName, inst, instances }, context) =>
|
|
1514
|
-
const sessionKeyValidation =
|
|
1812
|
+
.handler(async ({ recordName, inst, instances }, context) => {
|
|
1813
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
1515
1814
|
if (sessionKeyValidation.success === false) {
|
|
1516
1815
|
if (sessionKeyValidation.errorCode === 'no_session_key') {
|
|
1517
1816
|
return NOT_LOGGED_IN_RESULT;
|
|
1518
1817
|
}
|
|
1519
1818
|
return sessionKeyValidation;
|
|
1520
1819
|
}
|
|
1521
|
-
const result =
|
|
1820
|
+
const result = await this._policyController.listInstRoles(recordName, sessionKeyValidation.userId, inst, instances);
|
|
1522
1821
|
return result;
|
|
1523
|
-
})
|
|
1822
|
+
}),
|
|
1524
1823
|
listRoleAssignments: procedure()
|
|
1525
1824
|
.origins('api')
|
|
1526
1825
|
.http('GET', '/api/v2/records/role/assignments/list')
|
|
@@ -1542,8 +1841,8 @@ export class RecordsServer {
|
|
|
1542
1841
|
.optional(),
|
|
1543
1842
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1544
1843
|
}))
|
|
1545
|
-
.handler(({ recordName, role, startingRole, instances }, context) =>
|
|
1546
|
-
const sessionKeyValidation =
|
|
1844
|
+
.handler(async ({ recordName, role, startingRole, instances }, context) => {
|
|
1845
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
1547
1846
|
if (sessionKeyValidation.success === false) {
|
|
1548
1847
|
if (sessionKeyValidation.errorCode ===
|
|
1549
1848
|
'no_session_key') {
|
|
@@ -1552,14 +1851,14 @@ export class RecordsServer {
|
|
|
1552
1851
|
return sessionKeyValidation;
|
|
1553
1852
|
}
|
|
1554
1853
|
if (role) {
|
|
1555
|
-
const result =
|
|
1854
|
+
const result = await this._policyController.listAssignedRoles(recordName, sessionKeyValidation.userId, role, instances);
|
|
1556
1855
|
return result;
|
|
1557
1856
|
}
|
|
1558
1857
|
else {
|
|
1559
|
-
const result =
|
|
1858
|
+
const result = await this._policyController.listRoleAssignments(recordName, sessionKeyValidation.userId, startingRole, instances);
|
|
1560
1859
|
return result;
|
|
1561
1860
|
}
|
|
1562
|
-
})
|
|
1861
|
+
}),
|
|
1563
1862
|
grantRole: procedure()
|
|
1564
1863
|
.origins('api')
|
|
1565
1864
|
.http('POST', '/api/v2/records/role/grant')
|
|
@@ -1594,8 +1893,8 @@ export class RecordsServer {
|
|
|
1594
1893
|
.optional(),
|
|
1595
1894
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1596
1895
|
}))
|
|
1597
|
-
.handler(({ recordName, userId, inst, expireTimeMs, role, instances, }, context) =>
|
|
1598
|
-
const sessionKeyValidation =
|
|
1896
|
+
.handler(async ({ recordName, userId, inst, expireTimeMs, role, instances, }, context) => {
|
|
1897
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
1599
1898
|
if (sessionKeyValidation.success === false) {
|
|
1600
1899
|
if (sessionKeyValidation.errorCode ===
|
|
1601
1900
|
'no_session_key') {
|
|
@@ -1603,14 +1902,14 @@ export class RecordsServer {
|
|
|
1603
1902
|
}
|
|
1604
1903
|
return sessionKeyValidation;
|
|
1605
1904
|
}
|
|
1606
|
-
const result =
|
|
1905
|
+
const result = await this._policyController.grantRole(recordName, sessionKeyValidation.userId, {
|
|
1607
1906
|
instance: inst,
|
|
1608
1907
|
userId: userId,
|
|
1609
1908
|
role,
|
|
1610
1909
|
expireTimeMs,
|
|
1611
1910
|
}, instances);
|
|
1612
1911
|
return result;
|
|
1613
|
-
})
|
|
1912
|
+
}),
|
|
1614
1913
|
revokeRole: procedure()
|
|
1615
1914
|
.origins('api')
|
|
1616
1915
|
.http('POST', '/api/v2/records/role/revoke')
|
|
@@ -1638,8 +1937,8 @@ export class RecordsServer {
|
|
|
1638
1937
|
.nonempty('role must not be empty'),
|
|
1639
1938
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1640
1939
|
}))
|
|
1641
|
-
.handler(({ recordName, userId, inst, role, instances }, context) =>
|
|
1642
|
-
const sessionKeyValidation =
|
|
1940
|
+
.handler(async ({ recordName, userId, inst, role, instances }, context) => {
|
|
1941
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
1643
1942
|
if (sessionKeyValidation.success === false) {
|
|
1644
1943
|
if (sessionKeyValidation.errorCode ===
|
|
1645
1944
|
'no_session_key') {
|
|
@@ -1647,32 +1946,26 @@ export class RecordsServer {
|
|
|
1647
1946
|
}
|
|
1648
1947
|
return sessionKeyValidation;
|
|
1649
1948
|
}
|
|
1650
|
-
const result =
|
|
1949
|
+
const result = await this._policyController.revokeRole(recordName, sessionKeyValidation.userId, {
|
|
1651
1950
|
instance: inst,
|
|
1652
1951
|
userId: userId,
|
|
1653
1952
|
role,
|
|
1654
1953
|
}, instances);
|
|
1655
1954
|
return result;
|
|
1656
|
-
})
|
|
1657
|
-
|
|
1955
|
+
}),
|
|
1956
|
+
grantEntitlement: procedure()
|
|
1658
1957
|
.origins('api')
|
|
1659
|
-
.http('POST', '/api/v2/
|
|
1958
|
+
.http('POST', '/api/v2/records/entitlement/grants')
|
|
1660
1959
|
.inputs(z.object({
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
frequencyPenalty: z.number().min(-2).max(2).optional(),
|
|
1668
|
-
stopWords: z.array(z.string()).max(4).optional(),
|
|
1960
|
+
packageId: z.string().min(1).max(36),
|
|
1961
|
+
userId: z.string().optional().nullable(),
|
|
1962
|
+
recordName: RECORD_NAME_VALIDATION,
|
|
1963
|
+
feature: ENTITLEMENT_FEATURE_VALIDATION,
|
|
1964
|
+
scope: z.literal('designated'),
|
|
1965
|
+
expireTimeMs: z.number().min(1),
|
|
1669
1966
|
}))
|
|
1670
|
-
.handler((
|
|
1671
|
-
|
|
1672
|
-
if (!this._aiController) {
|
|
1673
|
-
return AI_NOT_SUPPORTED_RESULT;
|
|
1674
|
-
}
|
|
1675
|
-
const sessionKeyValidation = yield this._validateSessionKey(context.sessionKey);
|
|
1967
|
+
.handler(async ({ packageId, userId, recordName, feature, scope, expireTimeMs, }, context) => {
|
|
1968
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
1676
1969
|
if (sessionKeyValidation.success === false) {
|
|
1677
1970
|
if (sessionKeyValidation.errorCode ===
|
|
1678
1971
|
'no_session_key') {
|
|
@@ -1680,61 +1973,155 @@ export class RecordsServer {
|
|
|
1680
1973
|
}
|
|
1681
1974
|
return sessionKeyValidation;
|
|
1682
1975
|
}
|
|
1683
|
-
const result =
|
|
1976
|
+
const result = await this._policyController.grantEntitlement({
|
|
1977
|
+
packageId,
|
|
1978
|
+
userId: sessionKeyValidation.userId,
|
|
1979
|
+
userRole: sessionKeyValidation.role,
|
|
1980
|
+
grantingUserId: userId !== null && userId !== void 0 ? userId : sessionKeyValidation.userId,
|
|
1981
|
+
recordName,
|
|
1982
|
+
feature,
|
|
1983
|
+
scope,
|
|
1984
|
+
expireTimeMs,
|
|
1985
|
+
});
|
|
1684
1986
|
return result;
|
|
1685
|
-
})
|
|
1686
|
-
|
|
1987
|
+
}),
|
|
1988
|
+
revokeEntitlement: procedure()
|
|
1687
1989
|
.origins('api')
|
|
1688
|
-
.http('POST', '/api/v2/
|
|
1990
|
+
.http('POST', '/api/v2/records/entitlement/revoke')
|
|
1689
1991
|
.inputs(z.object({
|
|
1690
|
-
|
|
1691
|
-
messages: z.array(AI_CHAT_MESSAGE_SCHEMA).nonempty(),
|
|
1692
|
-
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1693
|
-
temperature: z.number().min(0).max(2).optional(),
|
|
1694
|
-
topP: z.number().optional(),
|
|
1695
|
-
presencePenalty: z.number().min(-2).max(2).optional(),
|
|
1696
|
-
frequencyPenalty: z.number().min(-2).max(2).optional(),
|
|
1697
|
-
stopWords: z.array(z.string()).max(4).optional(),
|
|
1992
|
+
grantId: z.string(),
|
|
1698
1993
|
}))
|
|
1699
|
-
.handler((
|
|
1700
|
-
|
|
1701
|
-
if (!this._aiController) {
|
|
1702
|
-
return AI_NOT_SUPPORTED_RESULT;
|
|
1703
|
-
}
|
|
1704
|
-
const sessionKeyValidation = yield this._validateSessionKey(context.sessionKey);
|
|
1994
|
+
.handler(async ({ grantId }, context) => {
|
|
1995
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
1705
1996
|
if (sessionKeyValidation.success === false) {
|
|
1706
1997
|
if (sessionKeyValidation.errorCode === 'no_session_key') {
|
|
1707
1998
|
return NOT_LOGGED_IN_RESULT;
|
|
1708
1999
|
}
|
|
1709
2000
|
return sessionKeyValidation;
|
|
1710
2001
|
}
|
|
1711
|
-
const result = this.
|
|
2002
|
+
const result = await this._policyController.revokeEntitlement({
|
|
2003
|
+
userId: sessionKeyValidation.userId,
|
|
2004
|
+
userRole: sessionKeyValidation.role,
|
|
2005
|
+
grantId,
|
|
2006
|
+
});
|
|
1712
2007
|
return result;
|
|
1713
|
-
})
|
|
1714
|
-
|
|
2008
|
+
}),
|
|
2009
|
+
listGrantedEntitlements: procedure()
|
|
1715
2010
|
.origins('api')
|
|
1716
|
-
.http('
|
|
2011
|
+
.http('GET', '/api/v2/records/entitlement/grants/list')
|
|
1717
2012
|
.inputs(z.object({
|
|
1718
|
-
|
|
1719
|
-
negativePrompt: z
|
|
2013
|
+
packageId: z
|
|
1720
2014
|
.string()
|
|
1721
|
-
.
|
|
1722
|
-
.max(
|
|
1723
|
-
.optional()
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
2015
|
+
.min(1)
|
|
2016
|
+
.max(36)
|
|
2017
|
+
.optional()
|
|
2018
|
+
.nullable(),
|
|
2019
|
+
}))
|
|
2020
|
+
.handler(async ({ packageId }, context) => {
|
|
2021
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
2022
|
+
if (sessionKeyValidation.success === false) {
|
|
2023
|
+
if (sessionKeyValidation.errorCode === 'no_session_key') {
|
|
2024
|
+
return NOT_LOGGED_IN_RESULT;
|
|
2025
|
+
}
|
|
2026
|
+
return sessionKeyValidation;
|
|
2027
|
+
}
|
|
2028
|
+
const result = await this._policyController.listGrantedEntitlements({
|
|
2029
|
+
userId: sessionKeyValidation.userId,
|
|
2030
|
+
packageId: packageId,
|
|
2031
|
+
});
|
|
2032
|
+
return result;
|
|
2033
|
+
}),
|
|
2034
|
+
aiChat: procedure()
|
|
2035
|
+
.origins('api')
|
|
2036
|
+
.http('POST', '/api/v2/ai/chat')
|
|
2037
|
+
.inputs(z.object({
|
|
2038
|
+
model: z.string().nonempty().optional(),
|
|
2039
|
+
messages: z.array(AI_CHAT_MESSAGE_SCHEMA).nonempty(),
|
|
2040
|
+
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
2041
|
+
temperature: z.number().min(0).max(2).optional(),
|
|
2042
|
+
topP: z.number().optional(),
|
|
2043
|
+
presencePenalty: z.number().min(-2).max(2).optional(),
|
|
2044
|
+
frequencyPenalty: z.number().min(-2).max(2).optional(),
|
|
2045
|
+
stopWords: z.array(z.string()).max(4).optional(),
|
|
2046
|
+
}))
|
|
2047
|
+
.handler(async ({ model, messages, instances, ...options }, context) => {
|
|
2048
|
+
if (!this._aiController) {
|
|
2049
|
+
return AI_NOT_SUPPORTED_RESULT;
|
|
2050
|
+
}
|
|
2051
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
2052
|
+
if (sessionKeyValidation.success === false) {
|
|
2053
|
+
if (sessionKeyValidation.errorCode ===
|
|
2054
|
+
'no_session_key') {
|
|
2055
|
+
return NOT_LOGGED_IN_RESULT;
|
|
2056
|
+
}
|
|
2057
|
+
return sessionKeyValidation;
|
|
2058
|
+
}
|
|
2059
|
+
const result = await this._aiController.chat({
|
|
2060
|
+
...options,
|
|
2061
|
+
model,
|
|
2062
|
+
messages: messages,
|
|
2063
|
+
userId: sessionKeyValidation.userId,
|
|
2064
|
+
userSubscriptionTier: sessionKeyValidation.subscriptionTier,
|
|
2065
|
+
});
|
|
2066
|
+
return result;
|
|
2067
|
+
}),
|
|
2068
|
+
aiChatStream: procedure()
|
|
2069
|
+
.origins('api')
|
|
2070
|
+
.http('POST', '/api/v2/ai/chat/stream')
|
|
2071
|
+
.inputs(z.object({
|
|
2072
|
+
model: z.string().nonempty().optional(),
|
|
2073
|
+
messages: z.array(AI_CHAT_MESSAGE_SCHEMA).nonempty(),
|
|
2074
|
+
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
2075
|
+
temperature: z.number().min(0).max(2).optional(),
|
|
2076
|
+
topP: z.number().optional(),
|
|
2077
|
+
presencePenalty: z.number().min(-2).max(2).optional(),
|
|
2078
|
+
frequencyPenalty: z.number().min(-2).max(2).optional(),
|
|
2079
|
+
stopWords: z.array(z.string()).max(4).optional(),
|
|
2080
|
+
}))
|
|
2081
|
+
.handler(async ({ model, messages, ...options }, context) => {
|
|
2082
|
+
if (!this._aiController) {
|
|
2083
|
+
return AI_NOT_SUPPORTED_RESULT;
|
|
2084
|
+
}
|
|
2085
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
2086
|
+
if (sessionKeyValidation.success === false) {
|
|
2087
|
+
if (sessionKeyValidation.errorCode === 'no_session_key') {
|
|
2088
|
+
return NOT_LOGGED_IN_RESULT;
|
|
2089
|
+
}
|
|
2090
|
+
return sessionKeyValidation;
|
|
2091
|
+
}
|
|
2092
|
+
const result = this._aiController.chatStream({
|
|
2093
|
+
...options,
|
|
2094
|
+
model,
|
|
2095
|
+
messages: messages,
|
|
2096
|
+
userId: sessionKeyValidation.userId,
|
|
2097
|
+
userSubscriptionTier: sessionKeyValidation.subscriptionTier,
|
|
2098
|
+
});
|
|
2099
|
+
return result;
|
|
2100
|
+
}),
|
|
2101
|
+
createAiSkybox: procedure()
|
|
2102
|
+
.origins('api')
|
|
2103
|
+
.http('POST', '/api/v2/ai/skybox')
|
|
2104
|
+
.inputs(z.object({
|
|
2105
|
+
prompt: z.string().nonempty().max(600),
|
|
2106
|
+
negativePrompt: z
|
|
2107
|
+
.string()
|
|
2108
|
+
.nonempty()
|
|
2109
|
+
.max(600)
|
|
2110
|
+
.optional(),
|
|
2111
|
+
blockadeLabs: z
|
|
2112
|
+
.object({
|
|
2113
|
+
skyboxStyleId: z.number().optional(),
|
|
2114
|
+
remixImagineId: z.number().optional(),
|
|
2115
|
+
seed: z.number().optional(),
|
|
2116
|
+
})
|
|
1730
2117
|
.optional(),
|
|
1731
2118
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1732
2119
|
}))
|
|
1733
|
-
.handler(({ prompt, negativePrompt, instances, blockadeLabs }, context) =>
|
|
2120
|
+
.handler(async ({ prompt, negativePrompt, instances, blockadeLabs }, context) => {
|
|
1734
2121
|
if (!this._aiController) {
|
|
1735
2122
|
return AI_NOT_SUPPORTED_RESULT;
|
|
1736
2123
|
}
|
|
1737
|
-
const sessionKeyValidation =
|
|
2124
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
1738
2125
|
if (sessionKeyValidation.success === false) {
|
|
1739
2126
|
if (sessionKeyValidation.errorCode ===
|
|
1740
2127
|
'no_session_key') {
|
|
@@ -1742,7 +2129,7 @@ export class RecordsServer {
|
|
|
1742
2129
|
}
|
|
1743
2130
|
return sessionKeyValidation;
|
|
1744
2131
|
}
|
|
1745
|
-
const result =
|
|
2132
|
+
const result = await this._aiController.generateSkybox({
|
|
1746
2133
|
prompt,
|
|
1747
2134
|
negativePrompt,
|
|
1748
2135
|
blockadeLabs,
|
|
@@ -1750,7 +2137,7 @@ export class RecordsServer {
|
|
|
1750
2137
|
userSubscriptionTier: sessionKeyValidation.subscriptionTier,
|
|
1751
2138
|
});
|
|
1752
2139
|
return result;
|
|
1753
|
-
})
|
|
2140
|
+
}),
|
|
1754
2141
|
getAiSkybox: procedure()
|
|
1755
2142
|
.origins('api')
|
|
1756
2143
|
.http('GET', '/api/v2/ai/skybox')
|
|
@@ -1763,24 +2150,24 @@ export class RecordsServer {
|
|
|
1763
2150
|
.nonempty('skyboxId must not be empty'),
|
|
1764
2151
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1765
2152
|
}))
|
|
1766
|
-
.handler(({ skyboxId, instances }, context) =>
|
|
2153
|
+
.handler(async ({ skyboxId, instances }, context) => {
|
|
1767
2154
|
if (!this._aiController) {
|
|
1768
2155
|
return AI_NOT_SUPPORTED_RESULT;
|
|
1769
2156
|
}
|
|
1770
|
-
const sessionKeyValidation =
|
|
2157
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
1771
2158
|
if (sessionKeyValidation.success === false) {
|
|
1772
2159
|
if (sessionKeyValidation.errorCode === 'no_session_key') {
|
|
1773
2160
|
return NOT_LOGGED_IN_RESULT;
|
|
1774
2161
|
}
|
|
1775
2162
|
return sessionKeyValidation;
|
|
1776
2163
|
}
|
|
1777
|
-
const result =
|
|
2164
|
+
const result = await this._aiController.getSkybox({
|
|
1778
2165
|
skyboxId,
|
|
1779
2166
|
userId: sessionKeyValidation.userId,
|
|
1780
2167
|
userSubscriptionTier: sessionKeyValidation.subscriptionTier,
|
|
1781
2168
|
});
|
|
1782
2169
|
return result;
|
|
1783
|
-
})
|
|
2170
|
+
}),
|
|
1784
2171
|
createAiImage: procedure()
|
|
1785
2172
|
.origins('api')
|
|
1786
2173
|
.http('POST', '/api/v2/ai/image')
|
|
@@ -1810,11 +2197,11 @@ export class RecordsServer {
|
|
|
1810
2197
|
stylePreset: z.string().nonempty().optional(),
|
|
1811
2198
|
instances: INSTANCES_ARRAY_VALIDATION.optional(),
|
|
1812
2199
|
}))
|
|
1813
|
-
.handler(({ prompt, model, negativePrompt, width, height, seed, numberOfImages, steps, sampler, cfgScale, clipGuidancePreset, stylePreset, instances, }, context) =>
|
|
2200
|
+
.handler(async ({ prompt, model, negativePrompt, width, height, seed, numberOfImages, steps, sampler, cfgScale, clipGuidancePreset, stylePreset, instances, }, context) => {
|
|
1814
2201
|
if (!this._aiController) {
|
|
1815
2202
|
return AI_NOT_SUPPORTED_RESULT;
|
|
1816
2203
|
}
|
|
1817
|
-
const sessionKeyValidation =
|
|
2204
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
1818
2205
|
if (sessionKeyValidation.success === false) {
|
|
1819
2206
|
if (sessionKeyValidation.errorCode ===
|
|
1820
2207
|
'no_session_key') {
|
|
@@ -1822,7 +2209,7 @@ export class RecordsServer {
|
|
|
1822
2209
|
}
|
|
1823
2210
|
return sessionKeyValidation;
|
|
1824
2211
|
}
|
|
1825
|
-
const result =
|
|
2212
|
+
const result = await this._aiController.generateImage({
|
|
1826
2213
|
model,
|
|
1827
2214
|
prompt,
|
|
1828
2215
|
negativePrompt,
|
|
@@ -1839,30 +2226,30 @@ export class RecordsServer {
|
|
|
1839
2226
|
userSubscriptionTier: sessionKeyValidation.subscriptionTier,
|
|
1840
2227
|
});
|
|
1841
2228
|
return result;
|
|
1842
|
-
})
|
|
2229
|
+
}),
|
|
1843
2230
|
getHumeAccessToken: procedure()
|
|
1844
2231
|
.origins('api')
|
|
1845
2232
|
.http('GET', '/api/v2/ai/hume/token')
|
|
1846
2233
|
.inputs(z.object({
|
|
1847
2234
|
recordName: RECORD_NAME_VALIDATION.optional(),
|
|
1848
2235
|
}))
|
|
1849
|
-
.handler(({ recordName }, context) =>
|
|
2236
|
+
.handler(async ({ recordName }, context) => {
|
|
1850
2237
|
if (!this._aiController) {
|
|
1851
2238
|
return AI_NOT_SUPPORTED_RESULT;
|
|
1852
2239
|
}
|
|
1853
|
-
const sessionKeyValidation =
|
|
2240
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
1854
2241
|
if (sessionKeyValidation.success === false) {
|
|
1855
2242
|
if (sessionKeyValidation.errorCode === 'no_session_key') {
|
|
1856
2243
|
return NOT_LOGGED_IN_RESULT;
|
|
1857
2244
|
}
|
|
1858
2245
|
return sessionKeyValidation;
|
|
1859
2246
|
}
|
|
1860
|
-
const result =
|
|
2247
|
+
const result = await this._aiController.getHumeAccessToken({
|
|
1861
2248
|
userId: sessionKeyValidation.userId,
|
|
1862
2249
|
recordName,
|
|
1863
2250
|
});
|
|
1864
2251
|
return result;
|
|
1865
|
-
})
|
|
2252
|
+
}),
|
|
1866
2253
|
createSloydModel: procedure()
|
|
1867
2254
|
.origins('api')
|
|
1868
2255
|
.http('POST', '/api/v2/ai/sloyd/model')
|
|
@@ -1882,11 +2269,11 @@ export class RecordsServer {
|
|
|
1882
2269
|
})
|
|
1883
2270
|
.optional(),
|
|
1884
2271
|
}))
|
|
1885
|
-
.handler(({ recordName, outputMimeType, prompt, levelOfDetail, baseModelId, thumbnail, }, context) =>
|
|
2272
|
+
.handler(async ({ recordName, outputMimeType, prompt, levelOfDetail, baseModelId, thumbnail, }, context) => {
|
|
1886
2273
|
if (!this._aiController) {
|
|
1887
2274
|
return AI_NOT_SUPPORTED_RESULT;
|
|
1888
2275
|
}
|
|
1889
|
-
const sessionKeyValidation =
|
|
2276
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
1890
2277
|
if (sessionKeyValidation.success === false) {
|
|
1891
2278
|
if (sessionKeyValidation.errorCode ===
|
|
1892
2279
|
'no_session_key') {
|
|
@@ -1894,7 +2281,7 @@ export class RecordsServer {
|
|
|
1894
2281
|
}
|
|
1895
2282
|
return sessionKeyValidation;
|
|
1896
2283
|
}
|
|
1897
|
-
const result =
|
|
2284
|
+
const result = await this._aiController.sloydGenerateModel({
|
|
1898
2285
|
userId: sessionKeyValidation.userId,
|
|
1899
2286
|
recordName: recordName !== null && recordName !== void 0 ? recordName : sessionKeyValidation.userId,
|
|
1900
2287
|
outputMimeType,
|
|
@@ -1904,30 +2291,30 @@ export class RecordsServer {
|
|
|
1904
2291
|
thumbnail: thumbnail,
|
|
1905
2292
|
});
|
|
1906
2293
|
return result;
|
|
1907
|
-
})
|
|
2294
|
+
}),
|
|
1908
2295
|
getLoomAccessToken: procedure()
|
|
1909
2296
|
.origins('api')
|
|
1910
2297
|
.http('GET', '/api/v2/loom/token')
|
|
1911
2298
|
.inputs(z.object({
|
|
1912
2299
|
recordName: RECORD_NAME_VALIDATION,
|
|
1913
2300
|
}))
|
|
1914
|
-
.handler(({ recordName }, context) =>
|
|
2301
|
+
.handler(async ({ recordName }, context) => {
|
|
1915
2302
|
if (!this._loomController) {
|
|
1916
2303
|
return LOOM_NOT_SUPPORTED_RESULT;
|
|
1917
2304
|
}
|
|
1918
|
-
const sessionKeyValidation =
|
|
2305
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
1919
2306
|
if (sessionKeyValidation.success === false) {
|
|
1920
2307
|
if (sessionKeyValidation.errorCode === 'no_session_key') {
|
|
1921
2308
|
return NOT_LOGGED_IN_RESULT;
|
|
1922
2309
|
}
|
|
1923
2310
|
return sessionKeyValidation;
|
|
1924
2311
|
}
|
|
1925
|
-
const result =
|
|
2312
|
+
const result = await this._loomController.getToken({
|
|
1926
2313
|
userId: sessionKeyValidation.userId,
|
|
1927
2314
|
recordName: recordName,
|
|
1928
2315
|
});
|
|
1929
2316
|
return result;
|
|
1930
|
-
})
|
|
2317
|
+
}),
|
|
1931
2318
|
createOpenAIRealtimeSession: procedure()
|
|
1932
2319
|
.origins('api')
|
|
1933
2320
|
.http('POST', '/api/v2/ai/openai/realtime/session')
|
|
@@ -2002,41 +2389,44 @@ export class RecordsServer {
|
|
|
2002
2389
|
voice: z.string().min(1).optional(),
|
|
2003
2390
|
}),
|
|
2004
2391
|
}))
|
|
2005
|
-
.handler(({ recordName, request }, context) =>
|
|
2392
|
+
.handler(async ({ recordName, request }, context) => {
|
|
2006
2393
|
if (!this._aiController) {
|
|
2007
2394
|
return AI_NOT_SUPPORTED_RESULT;
|
|
2008
2395
|
}
|
|
2009
|
-
const sessionKeyValidation =
|
|
2396
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
2010
2397
|
if (sessionKeyValidation.success === false) {
|
|
2011
2398
|
if (sessionKeyValidation.errorCode === 'no_session_key') {
|
|
2012
2399
|
return NOT_LOGGED_IN_RESULT;
|
|
2013
2400
|
}
|
|
2014
2401
|
return sessionKeyValidation;
|
|
2015
2402
|
}
|
|
2016
|
-
const result =
|
|
2403
|
+
const result = await this._aiController.createOpenAIRealtimeSessionToken({
|
|
2017
2404
|
userId: sessionKeyValidation.userId,
|
|
2018
2405
|
recordName: recordName,
|
|
2019
|
-
request:
|
|
2406
|
+
request: {
|
|
2407
|
+
model: request.model,
|
|
2408
|
+
...request,
|
|
2409
|
+
},
|
|
2020
2410
|
});
|
|
2021
2411
|
return result;
|
|
2022
|
-
})
|
|
2412
|
+
}),
|
|
2023
2413
|
getStudio: procedure()
|
|
2024
2414
|
.origins('account')
|
|
2025
2415
|
.http('GET', '/api/v2/studios')
|
|
2026
2416
|
.inputs(z.object({
|
|
2027
2417
|
studioId: STUDIO_ID_VALIDATION,
|
|
2028
2418
|
}))
|
|
2029
|
-
.handler(({ studioId }, context) =>
|
|
2030
|
-
const sessionKeyValidation =
|
|
2419
|
+
.handler(async ({ studioId }, context) => {
|
|
2420
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
2031
2421
|
if (sessionKeyValidation.success === false) {
|
|
2032
2422
|
if (sessionKeyValidation.errorCode === 'no_session_key') {
|
|
2033
2423
|
return NOT_LOGGED_IN_RESULT;
|
|
2034
2424
|
}
|
|
2035
2425
|
return sessionKeyValidation;
|
|
2036
2426
|
}
|
|
2037
|
-
const result =
|
|
2427
|
+
const result = await this._records.getStudio(studioId, sessionKeyValidation.userId);
|
|
2038
2428
|
return result;
|
|
2039
|
-
})
|
|
2429
|
+
}),
|
|
2040
2430
|
createStudio: procedure()
|
|
2041
2431
|
.origins('account')
|
|
2042
2432
|
.http('POST', '/api/v2/studios')
|
|
@@ -2051,8 +2441,8 @@ export class RecordsServer {
|
|
|
2051
2441
|
.nullable()
|
|
2052
2442
|
.optional(),
|
|
2053
2443
|
}))
|
|
2054
|
-
.handler(({ displayName, ownerStudioComId }, context) =>
|
|
2055
|
-
const sessionKeyValidation =
|
|
2444
|
+
.handler(async ({ displayName, ownerStudioComId }, context) => {
|
|
2445
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
2056
2446
|
if (sessionKeyValidation.success === false) {
|
|
2057
2447
|
if (sessionKeyValidation.errorCode === 'no_session_key') {
|
|
2058
2448
|
return NOT_LOGGED_IN_RESULT;
|
|
@@ -2060,14 +2450,14 @@ export class RecordsServer {
|
|
|
2060
2450
|
return sessionKeyValidation;
|
|
2061
2451
|
}
|
|
2062
2452
|
if (!ownerStudioComId) {
|
|
2063
|
-
const result =
|
|
2453
|
+
const result = await this._records.createStudio(displayName, sessionKeyValidation.userId);
|
|
2064
2454
|
return result;
|
|
2065
2455
|
}
|
|
2066
2456
|
else {
|
|
2067
|
-
const result =
|
|
2457
|
+
const result = await this._records.createStudioInComId(displayName, sessionKeyValidation.userId, ownerStudioComId);
|
|
2068
2458
|
return result;
|
|
2069
2459
|
}
|
|
2070
|
-
})
|
|
2460
|
+
}),
|
|
2071
2461
|
updateStudio: procedure()
|
|
2072
2462
|
.origins('account')
|
|
2073
2463
|
.http('PUT', '/api/v2/studios')
|
|
@@ -2089,8 +2479,8 @@ export class RecordsServer {
|
|
|
2089
2479
|
loomConfig: LOOM_CONFIG.optional(),
|
|
2090
2480
|
humeConfig: HUME_CONFIG.optional(),
|
|
2091
2481
|
}))
|
|
2092
|
-
.handler(({ id, displayName, logoUrl, comIdConfig, playerConfig, loomConfig, humeConfig, }, context) =>
|
|
2093
|
-
const sessionKeyValidation =
|
|
2482
|
+
.handler(async ({ id, displayName, logoUrl, comIdConfig, playerConfig, loomConfig, humeConfig, }, context) => {
|
|
2483
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
2094
2484
|
if (sessionKeyValidation.success === false) {
|
|
2095
2485
|
if (sessionKeyValidation.errorCode ===
|
|
2096
2486
|
'no_session_key') {
|
|
@@ -2098,7 +2488,7 @@ export class RecordsServer {
|
|
|
2098
2488
|
}
|
|
2099
2489
|
return sessionKeyValidation;
|
|
2100
2490
|
}
|
|
2101
|
-
const result =
|
|
2491
|
+
const result = await this._records.updateStudio({
|
|
2102
2492
|
userId: sessionKeyValidation.userId,
|
|
2103
2493
|
studio: {
|
|
2104
2494
|
id,
|
|
@@ -2111,7 +2501,7 @@ export class RecordsServer {
|
|
|
2111
2501
|
},
|
|
2112
2502
|
});
|
|
2113
2503
|
return result;
|
|
2114
|
-
})
|
|
2504
|
+
}),
|
|
2115
2505
|
requestStudioComId: procedure()
|
|
2116
2506
|
.origins('account')
|
|
2117
2507
|
.http('POST', '/api/v2/studios/requestComId')
|
|
@@ -2119,22 +2509,22 @@ export class RecordsServer {
|
|
|
2119
2509
|
studioId: STUDIO_ID_VALIDATION,
|
|
2120
2510
|
comId: COM_ID_VALIDATION,
|
|
2121
2511
|
}))
|
|
2122
|
-
.handler(({ studioId, comId }, context) =>
|
|
2123
|
-
const sessionKeyValidation =
|
|
2512
|
+
.handler(async ({ studioId, comId }, context) => {
|
|
2513
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
2124
2514
|
if (sessionKeyValidation.success === false) {
|
|
2125
2515
|
if (sessionKeyValidation.errorCode === 'no_session_key') {
|
|
2126
2516
|
return NOT_LOGGED_IN_RESULT;
|
|
2127
2517
|
}
|
|
2128
2518
|
return sessionKeyValidation;
|
|
2129
2519
|
}
|
|
2130
|
-
const result =
|
|
2520
|
+
const result = await this._records.requestComId({
|
|
2131
2521
|
studioId,
|
|
2132
2522
|
userId: sessionKeyValidation.userId,
|
|
2133
2523
|
requestedComId: comId,
|
|
2134
2524
|
ipAddress: context.ipAddress,
|
|
2135
2525
|
});
|
|
2136
2526
|
return result;
|
|
2137
|
-
})
|
|
2527
|
+
}),
|
|
2138
2528
|
listStudios: procedure()
|
|
2139
2529
|
.origins('api')
|
|
2140
2530
|
.http('GET', '/api/v2/studios/list')
|
|
@@ -2142,8 +2532,8 @@ export class RecordsServer {
|
|
|
2142
2532
|
comId: z.string().nonempty().nullable().optional(),
|
|
2143
2533
|
userId: z.string().optional(),
|
|
2144
2534
|
}))
|
|
2145
|
-
.handler(({ comId, userId }, context) =>
|
|
2146
|
-
const sessionKeyValidation =
|
|
2535
|
+
.handler(async ({ comId, userId }, context) => {
|
|
2536
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
2147
2537
|
if (sessionKeyValidation.success === false) {
|
|
2148
2538
|
if (sessionKeyValidation.errorCode === 'no_session_key') {
|
|
2149
2539
|
return NOT_LOGGED_IN_RESULT;
|
|
@@ -2163,31 +2553,31 @@ export class RecordsServer {
|
|
|
2163
2553
|
userId = sessionKeyValidation.userId;
|
|
2164
2554
|
}
|
|
2165
2555
|
if (comId) {
|
|
2166
|
-
const result =
|
|
2556
|
+
const result = await this._records.listStudiosByComId(userId, comId);
|
|
2167
2557
|
return result;
|
|
2168
2558
|
}
|
|
2169
2559
|
else {
|
|
2170
|
-
const result =
|
|
2560
|
+
const result = await this._records.listStudios(userId);
|
|
2171
2561
|
return result;
|
|
2172
2562
|
}
|
|
2173
|
-
})
|
|
2563
|
+
}),
|
|
2174
2564
|
listStudioMembers: procedure()
|
|
2175
2565
|
.origins('account')
|
|
2176
2566
|
.http('GET', '/api/v2/studios/members/list')
|
|
2177
2567
|
.inputs(z.object({
|
|
2178
2568
|
studioId: STUDIO_ID_VALIDATION,
|
|
2179
2569
|
}))
|
|
2180
|
-
.handler(({ studioId }, context) =>
|
|
2181
|
-
const sessionKeyValidation =
|
|
2570
|
+
.handler(async ({ studioId }, context) => {
|
|
2571
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
2182
2572
|
if (sessionKeyValidation.success === false) {
|
|
2183
2573
|
if (sessionKeyValidation.errorCode === 'no_session_key') {
|
|
2184
2574
|
return NOT_LOGGED_IN_RESULT;
|
|
2185
2575
|
}
|
|
2186
2576
|
return sessionKeyValidation;
|
|
2187
2577
|
}
|
|
2188
|
-
const result =
|
|
2578
|
+
const result = await this._records.listStudioMembers(studioId, sessionKeyValidation.userId);
|
|
2189
2579
|
return result;
|
|
2190
|
-
})
|
|
2580
|
+
}),
|
|
2191
2581
|
addStudioMember: procedure()
|
|
2192
2582
|
.origins('account')
|
|
2193
2583
|
.http('POST', '/api/v2/studios/members')
|
|
@@ -2226,8 +2616,8 @@ export class RecordsServer {
|
|
|
2226
2616
|
z.literal('member'),
|
|
2227
2617
|
]),
|
|
2228
2618
|
}))
|
|
2229
|
-
.handler(({ studioId, addedUserId, addedEmail, addedPhoneNumber, addedDisplayName, role, }, context) =>
|
|
2230
|
-
const sessionKeyValidation =
|
|
2619
|
+
.handler(async ({ studioId, addedUserId, addedEmail, addedPhoneNumber, addedDisplayName, role, }, context) => {
|
|
2620
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
2231
2621
|
if (sessionKeyValidation.success === false) {
|
|
2232
2622
|
if (sessionKeyValidation.errorCode ===
|
|
2233
2623
|
'no_session_key') {
|
|
@@ -2235,7 +2625,7 @@ export class RecordsServer {
|
|
|
2235
2625
|
}
|
|
2236
2626
|
return sessionKeyValidation;
|
|
2237
2627
|
}
|
|
2238
|
-
const result =
|
|
2628
|
+
const result = await this._records.addStudioMember({
|
|
2239
2629
|
studioId,
|
|
2240
2630
|
userId: sessionKeyValidation.userId,
|
|
2241
2631
|
role,
|
|
@@ -2245,7 +2635,7 @@ export class RecordsServer {
|
|
|
2245
2635
|
addedDisplayName,
|
|
2246
2636
|
});
|
|
2247
2637
|
return result;
|
|
2248
|
-
})
|
|
2638
|
+
}),
|
|
2249
2639
|
removeStudioMember: procedure()
|
|
2250
2640
|
.origins('account')
|
|
2251
2641
|
.http('DELETE', '/api/v2/studios/members')
|
|
@@ -2259,31 +2649,31 @@ export class RecordsServer {
|
|
|
2259
2649
|
.nonempty('removedUserId must not be empty')
|
|
2260
2650
|
.optional(),
|
|
2261
2651
|
}))
|
|
2262
|
-
.handler(({ studioId, removedUserId }, context) =>
|
|
2263
|
-
const sessionKeyValidation =
|
|
2652
|
+
.handler(async ({ studioId, removedUserId }, context) => {
|
|
2653
|
+
const sessionKeyValidation = await this._validateSessionKey(context.sessionKey);
|
|
2264
2654
|
if (sessionKeyValidation.success === false) {
|
|
2265
2655
|
if (sessionKeyValidation.errorCode === 'no_session_key') {
|
|
2266
2656
|
return NOT_LOGGED_IN_RESULT;
|
|
2267
2657
|
}
|
|
2268
2658
|
return sessionKeyValidation;
|
|
2269
2659
|
}
|
|
2270
|
-
const result =
|
|
2660
|
+
const result = await this._records.removeStudioMember({
|
|
2271
2661
|
studioId,
|
|
2272
2662
|
userId: sessionKeyValidation.userId,
|
|
2273
2663
|
removedUserId,
|
|
2274
2664
|
});
|
|
2275
2665
|
return result;
|
|
2276
|
-
})
|
|
2666
|
+
}),
|
|
2277
2667
|
getPlayerConfig: procedure()
|
|
2278
2668
|
.origins('api')
|
|
2279
2669
|
.http('GET', '/api/v2/player/config')
|
|
2280
2670
|
.inputs(z.object({
|
|
2281
2671
|
comId: z.string().nonempty(),
|
|
2282
2672
|
}))
|
|
2283
|
-
.handler(({ comId }, context) =>
|
|
2284
|
-
const result =
|
|
2673
|
+
.handler(async ({ comId }, context) => {
|
|
2674
|
+
const result = await this._records.getPlayerConfig(comId);
|
|
2285
2675
|
return result;
|
|
2286
|
-
})
|
|
2676
|
+
}),
|
|
2287
2677
|
getSubscriptions: procedure()
|
|
2288
2678
|
.origins('account')
|
|
2289
2679
|
.http('GET', '/api/v2/subscriptions')
|
|
@@ -2303,7 +2693,7 @@ export class RecordsServer {
|
|
|
2303
2693
|
.nonempty('userId must be non-empty.')
|
|
2304
2694
|
.optional(),
|
|
2305
2695
|
}))
|
|
2306
|
-
.handler(({ studioId, userId }, context) =>
|
|
2696
|
+
.handler(async ({ studioId, userId }, context) => {
|
|
2307
2697
|
if (!this._subscriptions) {
|
|
2308
2698
|
return SUBSCRIPTIONS_NOT_SUPPORTED_RESULT;
|
|
2309
2699
|
}
|
|
@@ -2311,7 +2701,7 @@ export class RecordsServer {
|
|
|
2311
2701
|
if (!sessionKey) {
|
|
2312
2702
|
return NOT_LOGGED_IN_RESULT;
|
|
2313
2703
|
}
|
|
2314
|
-
const result =
|
|
2704
|
+
const result = await this._subscriptions.getSubscriptionStatus({
|
|
2315
2705
|
sessionKey,
|
|
2316
2706
|
userId,
|
|
2317
2707
|
studioId,
|
|
@@ -2347,7 +2737,7 @@ export class RecordsServer {
|
|
|
2347
2737
|
defaultSubscription: s.defaultSubscription,
|
|
2348
2738
|
})),
|
|
2349
2739
|
};
|
|
2350
|
-
})
|
|
2740
|
+
}),
|
|
2351
2741
|
getManageSubscriptionLink: procedure()
|
|
2352
2742
|
.origins('account')
|
|
2353
2743
|
.http('POST', '/api/v2/subscriptions/manage')
|
|
@@ -2381,7 +2771,7 @@ export class RecordsServer {
|
|
|
2381
2771
|
})
|
|
2382
2772
|
.optional(),
|
|
2383
2773
|
}))
|
|
2384
|
-
.handler(({ userId, studioId, subscriptionId, expectedPrice }, context) =>
|
|
2774
|
+
.handler(async ({ userId, studioId, subscriptionId, expectedPrice }, context) => {
|
|
2385
2775
|
if (!this._subscriptions) {
|
|
2386
2776
|
return SUBSCRIPTIONS_NOT_SUPPORTED_RESULT;
|
|
2387
2777
|
}
|
|
@@ -2389,7 +2779,7 @@ export class RecordsServer {
|
|
|
2389
2779
|
if (!sessionKey) {
|
|
2390
2780
|
return NOT_LOGGED_IN_RESULT;
|
|
2391
2781
|
}
|
|
2392
|
-
const result =
|
|
2782
|
+
const result = await this._subscriptions.createManageSubscriptionLink({
|
|
2393
2783
|
sessionKey,
|
|
2394
2784
|
userId,
|
|
2395
2785
|
studioId,
|
|
@@ -2403,7 +2793,7 @@ export class RecordsServer {
|
|
|
2403
2793
|
success: true,
|
|
2404
2794
|
url: result.url,
|
|
2405
2795
|
};
|
|
2406
|
-
})
|
|
2796
|
+
}),
|
|
2407
2797
|
updateSubscription: procedure()
|
|
2408
2798
|
.origins('account')
|
|
2409
2799
|
.http('POST', '/api/v2/subscriptions/update')
|
|
@@ -2435,7 +2825,7 @@ export class RecordsServer {
|
|
|
2435
2825
|
.int()
|
|
2436
2826
|
.nullable(),
|
|
2437
2827
|
}))
|
|
2438
|
-
.handler(({ userId, studioId, subscriptionId, subscriptionStatus, subscriptionPeriodStartMs, subscriptionPeriodEndMs, }, context) =>
|
|
2828
|
+
.handler(async ({ userId, studioId, subscriptionId, subscriptionStatus, subscriptionPeriodStartMs, subscriptionPeriodEndMs, }, context) => {
|
|
2439
2829
|
if (!this._subscriptions) {
|
|
2440
2830
|
return SUBSCRIPTIONS_NOT_SUPPORTED_RESULT;
|
|
2441
2831
|
}
|
|
@@ -2443,11 +2833,11 @@ export class RecordsServer {
|
|
|
2443
2833
|
if (!sessionKey) {
|
|
2444
2834
|
return NOT_LOGGED_IN_RESULT;
|
|
2445
2835
|
}
|
|
2446
|
-
const validation =
|
|
2836
|
+
const validation = await this._validateSessionKey(sessionKey);
|
|
2447
2837
|
if (validation.success === false) {
|
|
2448
2838
|
return validation;
|
|
2449
2839
|
}
|
|
2450
|
-
const result =
|
|
2840
|
+
const result = await this._subscriptions.updateSubscription({
|
|
2451
2841
|
currentUserId: validation.userId,
|
|
2452
2842
|
currentUserRole: validation.role,
|
|
2453
2843
|
userId,
|
|
@@ -2458,7 +2848,7 @@ export class RecordsServer {
|
|
|
2458
2848
|
subscriptionPeriodEndMs,
|
|
2459
2849
|
});
|
|
2460
2850
|
return result;
|
|
2461
|
-
})
|
|
2851
|
+
}),
|
|
2462
2852
|
listInsts: procedure()
|
|
2463
2853
|
.origins('api')
|
|
2464
2854
|
.http('GET', '/api/v2/records/insts/list')
|
|
@@ -2466,7 +2856,7 @@ export class RecordsServer {
|
|
|
2466
2856
|
recordName: RECORD_NAME_VALIDATION.optional(),
|
|
2467
2857
|
inst: z.string().optional(),
|
|
2468
2858
|
}))
|
|
2469
|
-
.handler(({ recordName, inst }, context) =>
|
|
2859
|
+
.handler(async ({ recordName, inst }, context) => {
|
|
2470
2860
|
if (!this._websocketController) {
|
|
2471
2861
|
return INSTS_NOT_SUPPORTED_RESULT;
|
|
2472
2862
|
}
|
|
@@ -2474,14 +2864,14 @@ export class RecordsServer {
|
|
|
2474
2864
|
if (!sessionKey) {
|
|
2475
2865
|
return NOT_LOGGED_IN_RESULT;
|
|
2476
2866
|
}
|
|
2477
|
-
const validation =
|
|
2867
|
+
const validation = await this._validateSessionKey(sessionKey);
|
|
2478
2868
|
if (validation.success === false) {
|
|
2479
2869
|
return validation;
|
|
2480
2870
|
}
|
|
2481
2871
|
const userId = validation.userId;
|
|
2482
|
-
const result =
|
|
2872
|
+
const result = await this._websocketController.listInsts(recordName, userId, inst);
|
|
2483
2873
|
return result;
|
|
2484
|
-
})
|
|
2874
|
+
}),
|
|
2485
2875
|
deleteInst: procedure()
|
|
2486
2876
|
.origins('account')
|
|
2487
2877
|
.http('DELETE', '/api/v2/records/insts')
|
|
@@ -2490,7 +2880,7 @@ export class RecordsServer {
|
|
|
2490
2880
|
recordName: RECORD_NAME_VALIDATION.optional(),
|
|
2491
2881
|
inst: z.string().optional(),
|
|
2492
2882
|
}))
|
|
2493
|
-
.handler(({ recordKey, recordName, inst }, context) =>
|
|
2883
|
+
.handler(async ({ recordKey, recordName, inst }, context) => {
|
|
2494
2884
|
if (!this._websocketController) {
|
|
2495
2885
|
return INSTS_NOT_SUPPORTED_RESULT;
|
|
2496
2886
|
}
|
|
@@ -2498,13 +2888,13 @@ export class RecordsServer {
|
|
|
2498
2888
|
if (!sessionKey) {
|
|
2499
2889
|
return NOT_LOGGED_IN_RESULT;
|
|
2500
2890
|
}
|
|
2501
|
-
const validation =
|
|
2891
|
+
const validation = await this._validateSessionKey(sessionKey);
|
|
2502
2892
|
if (validation.success === false) {
|
|
2503
2893
|
return validation;
|
|
2504
2894
|
}
|
|
2505
|
-
const result =
|
|
2895
|
+
const result = await this._websocketController.eraseInst(recordKey !== null && recordKey !== void 0 ? recordKey : recordName, inst, validation.userId);
|
|
2506
2896
|
return result;
|
|
2507
|
-
})
|
|
2897
|
+
}),
|
|
2508
2898
|
reportInst: procedure()
|
|
2509
2899
|
.origins('api')
|
|
2510
2900
|
.http('POST', '/api/v2/records/insts/report')
|
|
@@ -2525,17 +2915,17 @@ export class RecordsServer {
|
|
|
2525
2915
|
reportedUrl: z.string().url(),
|
|
2526
2916
|
reportedPermalink: z.string().url(),
|
|
2527
2917
|
}))
|
|
2528
|
-
.handler(({ recordName, inst, automaticReport, reportReason, reportReasonText, reportedUrl, reportedPermalink, }, context) =>
|
|
2918
|
+
.handler(async ({ recordName, inst, automaticReport, reportReason, reportReasonText, reportedUrl, reportedPermalink, }, context) => {
|
|
2529
2919
|
if (!this._moderationController) {
|
|
2530
2920
|
return MODERATION_NOT_SUPPORTED_RESULT;
|
|
2531
2921
|
}
|
|
2532
|
-
const validation =
|
|
2922
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
2533
2923
|
if (validation.success === false) {
|
|
2534
2924
|
if (validation.errorCode !== 'no_session_key') {
|
|
2535
2925
|
return validation;
|
|
2536
2926
|
}
|
|
2537
2927
|
}
|
|
2538
|
-
const result =
|
|
2928
|
+
const result = await this._moderationController.reportInst({
|
|
2539
2929
|
recordName,
|
|
2540
2930
|
inst,
|
|
2541
2931
|
automaticReport,
|
|
@@ -2547,7 +2937,7 @@ export class RecordsServer {
|
|
|
2547
2937
|
reportingUserId: validation.userId,
|
|
2548
2938
|
});
|
|
2549
2939
|
return result;
|
|
2550
|
-
})
|
|
2940
|
+
}),
|
|
2551
2941
|
getInstData: procedure()
|
|
2552
2942
|
.origins(true)
|
|
2553
2943
|
.http('GET', '/instData')
|
|
@@ -2559,9 +2949,9 @@ export class RecordsServer {
|
|
|
2559
2949
|
.nonempty()
|
|
2560
2950
|
.default(DEFAULT_BRANCH_NAME),
|
|
2561
2951
|
}))
|
|
2562
|
-
.handler(({ recordName, inst, branch }, context) =>
|
|
2952
|
+
.handler(async ({ recordName, inst, branch }, context) => {
|
|
2563
2953
|
let userId = null;
|
|
2564
|
-
const validation =
|
|
2954
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
2565
2955
|
if (validation.success === false) {
|
|
2566
2956
|
if (validation.errorCode === 'no_session_key') {
|
|
2567
2957
|
userId = null;
|
|
@@ -2573,18 +2963,26 @@ export class RecordsServer {
|
|
|
2573
2963
|
else {
|
|
2574
2964
|
userId = validation.userId;
|
|
2575
2965
|
}
|
|
2576
|
-
const data =
|
|
2577
|
-
return
|
|
2578
|
-
|
|
2966
|
+
const data = await this._websocketController.getBranchData(userId, recordName !== null && recordName !== void 0 ? recordName : null, inst, branch);
|
|
2967
|
+
return {
|
|
2968
|
+
success: true,
|
|
2969
|
+
...data,
|
|
2970
|
+
};
|
|
2971
|
+
}),
|
|
2579
2972
|
listProcedures: procedure()
|
|
2580
2973
|
.origins(true)
|
|
2581
2974
|
.http('GET', '/api/v2/procedures')
|
|
2582
2975
|
.inputs(z.object({}))
|
|
2583
|
-
.handler((_, context) =>
|
|
2976
|
+
.handler(async (_, context) => {
|
|
2584
2977
|
const procedures = this._procedures;
|
|
2585
2978
|
const metadata = getProcedureMetadata(procedures);
|
|
2586
|
-
return
|
|
2587
|
-
|
|
2979
|
+
return {
|
|
2980
|
+
success: true,
|
|
2981
|
+
...metadata,
|
|
2982
|
+
version: typeof GIT_TAG === 'string' ? GIT_TAG : undefined,
|
|
2983
|
+
versionHash: typeof GIT_HASH === 'string' ? GIT_HASH : undefined,
|
|
2984
|
+
};
|
|
2985
|
+
}),
|
|
2588
2986
|
};
|
|
2589
2987
|
}
|
|
2590
2988
|
_setupRoutes() {
|
|
@@ -2605,7 +3003,7 @@ export class RecordsServer {
|
|
|
2605
3003
|
input: z.any().optional(),
|
|
2606
3004
|
query: z.any().optional(),
|
|
2607
3005
|
}),
|
|
2608
|
-
handler: (request, { procedure, input, query }) =>
|
|
3006
|
+
handler: async (request, { procedure, input, query }) => {
|
|
2609
3007
|
var _a, _b;
|
|
2610
3008
|
const proc = procs[procedure];
|
|
2611
3009
|
if (!proc) {
|
|
@@ -2648,13 +3046,13 @@ export class RecordsServer {
|
|
|
2648
3046
|
}
|
|
2649
3047
|
queryData = parseResult.data;
|
|
2650
3048
|
}
|
|
2651
|
-
result =
|
|
3049
|
+
result = await proc.handler(parseResult.data, context, queryData);
|
|
2652
3050
|
}
|
|
2653
3051
|
else {
|
|
2654
|
-
result =
|
|
3052
|
+
result = await proc.handler(input, context);
|
|
2655
3053
|
}
|
|
2656
3054
|
return returnProcedureOutput(result);
|
|
2657
|
-
}
|
|
3055
|
+
},
|
|
2658
3056
|
});
|
|
2659
3057
|
this.addRoute({
|
|
2660
3058
|
method: 'POST',
|
|
@@ -2702,7 +3100,7 @@ export class RecordsServer {
|
|
|
2702
3100
|
schema: procedure.schema,
|
|
2703
3101
|
querySchema: procedure.querySchema,
|
|
2704
3102
|
name: name,
|
|
2705
|
-
handler: (request, data, query) =>
|
|
3103
|
+
handler: async (request, data, query) => {
|
|
2706
3104
|
var _a;
|
|
2707
3105
|
const context = {
|
|
2708
3106
|
ipAddress: request.ipAddress,
|
|
@@ -2710,14 +3108,14 @@ export class RecordsServer {
|
|
|
2710
3108
|
httpRequest: request,
|
|
2711
3109
|
origin: (_a = request.headers.origin) !== null && _a !== void 0 ? _a : null,
|
|
2712
3110
|
};
|
|
2713
|
-
const result =
|
|
3111
|
+
const result = await procedure.handler(data, context, query);
|
|
2714
3112
|
const response = returnProcedureOutput(result);
|
|
2715
3113
|
if (procedure.mapToResponse) {
|
|
2716
|
-
const procedureResponse =
|
|
3114
|
+
const procedureResponse = await procedure.mapToResponse(result, context);
|
|
2717
3115
|
return merge(response, procedureResponse);
|
|
2718
3116
|
}
|
|
2719
3117
|
return response;
|
|
2720
|
-
}
|
|
3118
|
+
},
|
|
2721
3119
|
allowedOrigins: procedure.allowedOrigins,
|
|
2722
3120
|
};
|
|
2723
3121
|
this.addRoute(r);
|
|
@@ -2744,360 +3142,351 @@ export class RecordsServer {
|
|
|
2744
3142
|
* Handles the given request and returns the specified response.
|
|
2745
3143
|
* @param request The request that should be handled.
|
|
2746
3144
|
*/
|
|
2747
|
-
handleHttpRequest(request) {
|
|
3145
|
+
async handleHttpRequest(request) {
|
|
2748
3146
|
var _a;
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
3147
|
+
const span = trace.getActiveSpan();
|
|
3148
|
+
if (span) {
|
|
3149
|
+
const url = new URL(request.path, `http://${request.headers.host}`);
|
|
3150
|
+
span.setAttributes({
|
|
3151
|
+
[SEMATTRS_HTTP_METHOD]: request.method,
|
|
3152
|
+
[SEMATTRS_HTTP_URL]: url.href,
|
|
3153
|
+
[SEMATTRS_HTTP_TARGET]: request.path,
|
|
3154
|
+
[SEMATTRS_HTTP_CLIENT_IP]: request.ipAddress,
|
|
3155
|
+
[SEMATTRS_HTTP_HOST]: request.headers.host,
|
|
3156
|
+
[SEMATTRS_HTTP_USER_AGENT]: request.headers['user-agent'],
|
|
3157
|
+
['http.origin']: request.headers.origin,
|
|
3158
|
+
});
|
|
3159
|
+
}
|
|
3160
|
+
let skipRateLimitCheck = false;
|
|
3161
|
+
if (!this._rateLimit) {
|
|
3162
|
+
skipRateLimitCheck = true;
|
|
3163
|
+
}
|
|
3164
|
+
else if (request.method == 'POST' &&
|
|
3165
|
+
request.path === '/api/stripeWebhook') {
|
|
3166
|
+
skipRateLimitCheck = true;
|
|
3167
|
+
}
|
|
3168
|
+
if (skipRateLimitCheck && span) {
|
|
3169
|
+
span.setAttribute('request.rateLimitCheck', 'skipped');
|
|
3170
|
+
}
|
|
3171
|
+
if (!skipRateLimitCheck) {
|
|
3172
|
+
const response = await this._rateLimit.checkRateLimit({
|
|
3173
|
+
ipAddress: request.ipAddress,
|
|
3174
|
+
});
|
|
3175
|
+
if (response.success === false) {
|
|
3176
|
+
if (response.errorCode === 'rate_limit_exceeded') {
|
|
3177
|
+
return formatResponse(request, returnResult(response), true);
|
|
3178
|
+
}
|
|
3179
|
+
else {
|
|
3180
|
+
console.log('[RecordsServer] Rate limit check failed. Allowing request to continue.');
|
|
3181
|
+
}
|
|
2766
3182
|
}
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
3183
|
+
}
|
|
3184
|
+
if (request.method === 'GET' &&
|
|
3185
|
+
request.path.startsWith('/api/') &&
|
|
3186
|
+
request.path.endsWith('/metadata') &&
|
|
3187
|
+
!!request.pathParams.userId) {
|
|
3188
|
+
return formatResponse(request, await this._getUserInfo(request), this._allowedAccountOrigins);
|
|
3189
|
+
}
|
|
3190
|
+
else if (request.method === 'PUT' &&
|
|
3191
|
+
request.path.startsWith('/api/') &&
|
|
3192
|
+
request.path.endsWith('/metadata') &&
|
|
3193
|
+
!!request.pathParams.userId) {
|
|
3194
|
+
return formatResponse(request, await this._putUserInfo(request), this._allowedAccountOrigins);
|
|
3195
|
+
}
|
|
3196
|
+
else if (request.method === 'GET' &&
|
|
3197
|
+
request.path.startsWith('/api/') &&
|
|
3198
|
+
request.path.endsWith('/subscription') &&
|
|
3199
|
+
!!request.pathParams.userId) {
|
|
3200
|
+
return formatResponse(request, await this._getSubscriptionInfo(request), this._allowedAccountOrigins);
|
|
3201
|
+
}
|
|
3202
|
+
else if (request.method === 'POST' &&
|
|
3203
|
+
request.path.startsWith('/api/') &&
|
|
3204
|
+
request.path.endsWith('/subscription/manage') &&
|
|
3205
|
+
!!request.pathParams.userId) {
|
|
3206
|
+
return formatResponse(request, await this._manageSubscription(request), this._allowedAccountOrigins);
|
|
3207
|
+
}
|
|
3208
|
+
else if (request.method === 'OPTIONS' &&
|
|
3209
|
+
request.path.startsWith('/api/v2/records/file/')) {
|
|
3210
|
+
return formatResponse(request, await this._handleRecordFileOptions(request), this._allowedApiOrigins);
|
|
3211
|
+
}
|
|
3212
|
+
else if (request.method === 'OPTIONS') {
|
|
3213
|
+
return formatResponse(request, await this._handleOptions(request), true);
|
|
3214
|
+
}
|
|
3215
|
+
const route = this._routes.get(`${request.method}:${request.path}`);
|
|
3216
|
+
if (route) {
|
|
3217
|
+
if (span && route.name) {
|
|
3218
|
+
span.updateName(`http:${route.name}`);
|
|
2770
3219
|
}
|
|
2771
|
-
|
|
2772
|
-
|
|
3220
|
+
const origins = route.allowedOrigins === 'account'
|
|
3221
|
+
? this._allowedAccountOrigins
|
|
3222
|
+
: route.allowedOrigins === 'api'
|
|
3223
|
+
? this._allowedApiOrigins
|
|
3224
|
+
: (_a = route.allowedOrigins) !== null && _a !== void 0 ? _a : true;
|
|
3225
|
+
if (origins !== true && !validateOrigin(request, origins)) {
|
|
3226
|
+
return formatResponse(request, returnResult(INVALID_ORIGIN_RESULT), origins);
|
|
2773
3227
|
}
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
3228
|
+
try {
|
|
3229
|
+
let response;
|
|
3230
|
+
if (route.schema) {
|
|
3231
|
+
let data;
|
|
3232
|
+
if (request.method === 'GET' || request.method === 'HEAD') {
|
|
3233
|
+
const parseResult = route.schema.safeParse(request.query);
|
|
3234
|
+
if (parseResult.success === false) {
|
|
3235
|
+
return formatResponse(request, returnZodError(parseResult.error), origins);
|
|
3236
|
+
}
|
|
3237
|
+
data = parseResult.data;
|
|
2781
3238
|
}
|
|
2782
3239
|
else {
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
}
|
|
2786
|
-
}
|
|
2787
|
-
if (request.method === 'GET' &&
|
|
2788
|
-
request.path.startsWith('/api/') &&
|
|
2789
|
-
request.path.endsWith('/metadata') &&
|
|
2790
|
-
!!request.pathParams.userId) {
|
|
2791
|
-
return formatResponse(request, yield this._getUserInfo(request), this._allowedAccountOrigins);
|
|
2792
|
-
}
|
|
2793
|
-
else if (request.method === 'PUT' &&
|
|
2794
|
-
request.path.startsWith('/api/') &&
|
|
2795
|
-
request.path.endsWith('/metadata') &&
|
|
2796
|
-
!!request.pathParams.userId) {
|
|
2797
|
-
return formatResponse(request, yield this._putUserInfo(request), this._allowedAccountOrigins);
|
|
2798
|
-
}
|
|
2799
|
-
else if (request.method === 'GET' &&
|
|
2800
|
-
request.path.startsWith('/api/') &&
|
|
2801
|
-
request.path.endsWith('/subscription') &&
|
|
2802
|
-
!!request.pathParams.userId) {
|
|
2803
|
-
return formatResponse(request, yield this._getSubscriptionInfo(request), this._allowedAccountOrigins);
|
|
2804
|
-
}
|
|
2805
|
-
else if (request.method === 'POST' &&
|
|
2806
|
-
request.path.startsWith('/api/') &&
|
|
2807
|
-
request.path.endsWith('/subscription/manage') &&
|
|
2808
|
-
!!request.pathParams.userId) {
|
|
2809
|
-
return formatResponse(request, yield this._manageSubscription(request), this._allowedAccountOrigins);
|
|
2810
|
-
}
|
|
2811
|
-
else if (request.method === 'OPTIONS' &&
|
|
2812
|
-
request.path.startsWith('/api/v2/records/file/')) {
|
|
2813
|
-
return formatResponse(request, yield this._handleRecordFileOptions(request), this._allowedApiOrigins);
|
|
2814
|
-
}
|
|
2815
|
-
else if (request.method === 'OPTIONS') {
|
|
2816
|
-
return formatResponse(request, yield this._handleOptions(request), true);
|
|
2817
|
-
}
|
|
2818
|
-
const route = this._routes.get(`${request.method}:${request.path}`);
|
|
2819
|
-
if (route) {
|
|
2820
|
-
if (span && route.name) {
|
|
2821
|
-
span.updateName(`http:${route.name}`);
|
|
2822
|
-
}
|
|
2823
|
-
const origins = route.allowedOrigins === 'account'
|
|
2824
|
-
? this._allowedAccountOrigins
|
|
2825
|
-
: route.allowedOrigins === 'api'
|
|
2826
|
-
? this._allowedApiOrigins
|
|
2827
|
-
: (_a = route.allowedOrigins) !== null && _a !== void 0 ? _a : true;
|
|
2828
|
-
if (origins !== true && !validateOrigin(request, origins)) {
|
|
2829
|
-
return formatResponse(request, returnResult(INVALID_ORIGIN_RESULT), origins);
|
|
2830
|
-
}
|
|
2831
|
-
try {
|
|
2832
|
-
let response;
|
|
2833
|
-
if (route.schema) {
|
|
2834
|
-
let data;
|
|
2835
|
-
if (request.method === 'GET' || request.method === 'HEAD') {
|
|
2836
|
-
const parseResult = route.schema.safeParse(request.query);
|
|
2837
|
-
if (parseResult.success === false) {
|
|
2838
|
-
return formatResponse(request, returnZodError(parseResult.error), origins);
|
|
2839
|
-
}
|
|
2840
|
-
data = parseResult.data;
|
|
3240
|
+
if (typeof request.body !== 'string') {
|
|
3241
|
+
return formatResponse(request, returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON), origins);
|
|
2841
3242
|
}
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
const jsonResult = tryParseJson(request.body);
|
|
2847
|
-
if (!jsonResult.success ||
|
|
2848
|
-
typeof jsonResult.value !== 'object') {
|
|
2849
|
-
return formatResponse(request, returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON), origins);
|
|
2850
|
-
}
|
|
2851
|
-
const parseResult = route.schema.safeParse(jsonResult.value);
|
|
2852
|
-
if (parseResult.success === false) {
|
|
2853
|
-
return formatResponse(request, returnZodError(parseResult.error), origins);
|
|
2854
|
-
}
|
|
2855
|
-
data = parseResult.data;
|
|
3243
|
+
const jsonResult = tryParseJson(request.body);
|
|
3244
|
+
if (!jsonResult.success ||
|
|
3245
|
+
typeof jsonResult.value !== 'object') {
|
|
3246
|
+
return formatResponse(request, returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON), origins);
|
|
2856
3247
|
}
|
|
2857
|
-
|
|
2858
|
-
if (
|
|
2859
|
-
|
|
2860
|
-
if (parseResult.success === false) {
|
|
2861
|
-
return formatResponse(request, returnZodError(parseResult.error), origins);
|
|
2862
|
-
}
|
|
2863
|
-
query = parseResult.data;
|
|
3248
|
+
const parseResult = route.schema.safeParse(jsonResult.value);
|
|
3249
|
+
if (parseResult.success === false) {
|
|
3250
|
+
return formatResponse(request, returnZodError(parseResult.error), origins);
|
|
2864
3251
|
}
|
|
2865
|
-
|
|
2866
|
-
}
|
|
2867
|
-
else {
|
|
2868
|
-
response = yield route.handler(request);
|
|
3252
|
+
data = parseResult.data;
|
|
2869
3253
|
}
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
3254
|
+
let query;
|
|
3255
|
+
if (route.querySchema) {
|
|
3256
|
+
const parseResult = route.schema.safeParse(request.query);
|
|
3257
|
+
if (parseResult.success === false) {
|
|
3258
|
+
return formatResponse(request, returnZodError(parseResult.error), origins);
|
|
3259
|
+
}
|
|
3260
|
+
query = parseResult.data;
|
|
2875
3261
|
}
|
|
3262
|
+
response = await route.handler(request, data, query);
|
|
2876
3263
|
}
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
3264
|
+
else {
|
|
3265
|
+
response = await route.handler(request);
|
|
3266
|
+
}
|
|
3267
|
+
if (response) {
|
|
3268
|
+
return formatResponse(request, response, origins);
|
|
3269
|
+
}
|
|
3270
|
+
else {
|
|
3271
|
+
return formatResponse(request, returnResult({ success: true }), origins);
|
|
2884
3272
|
}
|
|
2885
3273
|
}
|
|
2886
|
-
|
|
2887
|
-
|
|
3274
|
+
catch (err) {
|
|
3275
|
+
console.error('[RecordsServer] Error while handling request: ', err, request);
|
|
3276
|
+
return formatResponse(request, returnResult({
|
|
3277
|
+
success: false,
|
|
3278
|
+
errorCode: 'server_error',
|
|
3279
|
+
errorMessage: 'A server error occurred.',
|
|
3280
|
+
}), origins);
|
|
3281
|
+
}
|
|
3282
|
+
}
|
|
3283
|
+
return formatResponse(request, returnResult(OPERATION_NOT_FOUND_RESULT), true);
|
|
2888
3284
|
}
|
|
2889
3285
|
/**
|
|
2890
3286
|
* Handles the given request and returns the specified response.
|
|
2891
3287
|
* @param request The request that should be handled.
|
|
2892
3288
|
*/
|
|
2893
|
-
handleWebsocketRequest(request) {
|
|
3289
|
+
async handleWebsocketRequest(request) {
|
|
2894
3290
|
var _a;
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
if (response.
|
|
2920
|
-
|
|
2921
|
-
yield this._websocketController.rateLimitExceeded(request.connectionId, (_a = response.retryAfterSeconds) !== null && _a !== void 0 ? _a : 0, response.totalHits, Date.now());
|
|
2922
|
-
return;
|
|
2923
|
-
}
|
|
2924
|
-
else {
|
|
2925
|
-
console.log('[RecordsServer] Websocket rate limit check failed. Allowing request to continue.');
|
|
2926
|
-
}
|
|
2927
|
-
}
|
|
2928
|
-
}
|
|
2929
|
-
if (skipRateLimitCheck && span) {
|
|
2930
|
-
span.setAttribute('request.rateLimitCheck', 'skipped');
|
|
2931
|
-
}
|
|
2932
|
-
if (request.type === 'connect') {
|
|
2933
|
-
console.log(`[RecordsServer] Connection recieved: `, request.connectionId);
|
|
2934
|
-
}
|
|
2935
|
-
else if (request.type === 'disconnect') {
|
|
2936
|
-
console.log(`[RecordsServer] Disconnection recieved: `, request.connectionId);
|
|
2937
|
-
yield this._websocketController.disconnect(request.connectionId);
|
|
2938
|
-
}
|
|
2939
|
-
else if (request.type === 'message') {
|
|
2940
|
-
if (typeof request.body !== 'string') {
|
|
2941
|
-
// Bad request
|
|
2942
|
-
return;
|
|
2943
|
-
}
|
|
2944
|
-
const jsonResult = tryParseJson(request.body);
|
|
2945
|
-
if (!jsonResult.success || typeof jsonResult.value !== 'object') {
|
|
2946
|
-
return;
|
|
2947
|
-
}
|
|
2948
|
-
const parseResult = websocketEventSchema.safeParse(jsonResult.value);
|
|
2949
|
-
if (parseResult.success === false) {
|
|
2950
|
-
yield this._sendWebsocketZodError(request.connectionId, null, parseResult.error);
|
|
3291
|
+
if (!this._websocketController) {
|
|
3292
|
+
return;
|
|
3293
|
+
}
|
|
3294
|
+
const span = trace.getActiveSpan();
|
|
3295
|
+
if (span) {
|
|
3296
|
+
span.setAttributes({
|
|
3297
|
+
[SEMATTRS_HTTP_CLIENT_IP]: request.ipAddress,
|
|
3298
|
+
['http.origin']: request.origin,
|
|
3299
|
+
['websocket.type']: request.type,
|
|
3300
|
+
['request.connectionId']: request.connectionId,
|
|
3301
|
+
});
|
|
3302
|
+
}
|
|
3303
|
+
let skipRateLimitCheck = false;
|
|
3304
|
+
if (!this._websocketRateLimit) {
|
|
3305
|
+
skipRateLimitCheck = true;
|
|
3306
|
+
}
|
|
3307
|
+
else if (request.type !== 'message') {
|
|
3308
|
+
skipRateLimitCheck = true;
|
|
3309
|
+
}
|
|
3310
|
+
if (!skipRateLimitCheck) {
|
|
3311
|
+
const response = await this._websocketRateLimit.checkRateLimit({
|
|
3312
|
+
ipAddress: request.ipAddress,
|
|
3313
|
+
});
|
|
3314
|
+
if (response.success === false) {
|
|
3315
|
+
if (response.errorCode === 'rate_limit_exceeded') {
|
|
3316
|
+
await this._websocketController.rateLimitExceeded(request.connectionId, (_a = response.retryAfterSeconds) !== null && _a !== void 0 ? _a : 0, response.totalHits, Date.now());
|
|
2951
3317
|
return;
|
|
2952
3318
|
}
|
|
2953
|
-
let [type, requestId, ...rest] = parseResult.data;
|
|
2954
|
-
if (type === WebsocketEventTypes.Message) {
|
|
2955
|
-
const [message] = rest;
|
|
2956
|
-
return yield this._processWebsocketMessage(request, requestId, message);
|
|
2957
|
-
}
|
|
2958
|
-
else if (type === WebsocketEventTypes.UploadRequest) {
|
|
2959
|
-
return yield this._processWebsocketUploadRequest(request, requestId);
|
|
2960
|
-
}
|
|
2961
|
-
else if (type === WebsocketEventTypes.DownloadRequest) {
|
|
2962
|
-
const [url, method, headers] = rest;
|
|
2963
|
-
return yield this._processWebsocketDownload(request, requestId, url, method, headers);
|
|
2964
|
-
}
|
|
2965
3319
|
else {
|
|
2966
|
-
|
|
2967
|
-
return;
|
|
3320
|
+
console.log('[RecordsServer] Websocket rate limit check failed. Allowing request to continue.');
|
|
2968
3321
|
}
|
|
2969
3322
|
}
|
|
2970
|
-
}
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
}
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
const span = trace.getActiveSpan();
|
|
2985
|
-
const messageResult = websocketRequestMessageSchema.safeParse(message);
|
|
2986
|
-
if (messageResult.success === false) {
|
|
2987
|
-
span === null || span === void 0 ? void 0 : span.setAttribute('request.messageType', 'invalid');
|
|
2988
|
-
yield this._sendWebsocketZodError(request.connectionId, requestId, messageResult.error);
|
|
3323
|
+
}
|
|
3324
|
+
if (skipRateLimitCheck && span) {
|
|
3325
|
+
span.setAttribute('request.rateLimitCheck', 'skipped');
|
|
3326
|
+
}
|
|
3327
|
+
if (request.type === 'connect') {
|
|
3328
|
+
console.log(`[RecordsServer] Connection recieved: `, request.connectionId);
|
|
3329
|
+
}
|
|
3330
|
+
else if (request.type === 'disconnect') {
|
|
3331
|
+
console.log(`[RecordsServer] Disconnection recieved: `, request.connectionId);
|
|
3332
|
+
await this._websocketController.disconnect(request.connectionId);
|
|
3333
|
+
}
|
|
3334
|
+
else if (request.type === 'message') {
|
|
3335
|
+
if (typeof request.body !== 'string') {
|
|
3336
|
+
// Bad request
|
|
2989
3337
|
return;
|
|
2990
3338
|
}
|
|
2991
|
-
const
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
yield this._websocketController.login(request.connectionId, requestId, data);
|
|
3339
|
+
const jsonResult = tryParseJson(request.body);
|
|
3340
|
+
if (!jsonResult.success || typeof jsonResult.value !== 'object') {
|
|
3341
|
+
return;
|
|
2995
3342
|
}
|
|
2996
|
-
|
|
2997
|
-
|
|
3343
|
+
const parseResult = websocketEventSchema.safeParse(jsonResult.value);
|
|
3344
|
+
if (parseResult.success === false) {
|
|
3345
|
+
await this._sendWebsocketZodError(request.connectionId, null, parseResult.error);
|
|
3346
|
+
return;
|
|
2998
3347
|
}
|
|
2999
|
-
|
|
3000
|
-
|
|
3348
|
+
let [type, requestId, ...rest] = parseResult.data;
|
|
3349
|
+
if (type === WebsocketEventTypes.Message) {
|
|
3350
|
+
const [message] = rest;
|
|
3351
|
+
return await this._processWebsocketMessage(request, requestId, message);
|
|
3001
3352
|
}
|
|
3002
|
-
else if (
|
|
3003
|
-
|
|
3353
|
+
else if (type === WebsocketEventTypes.UploadRequest) {
|
|
3354
|
+
return await this._processWebsocketUploadRequest(request, requestId);
|
|
3004
3355
|
}
|
|
3005
|
-
else if (
|
|
3006
|
-
|
|
3356
|
+
else if (type === WebsocketEventTypes.DownloadRequest) {
|
|
3357
|
+
const [url, method, headers] = rest;
|
|
3358
|
+
return await this._processWebsocketDownload(request, requestId, url, method, headers);
|
|
3007
3359
|
}
|
|
3008
|
-
else
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
else if (data.type === 'repo/watch_branch_devices') {
|
|
3012
|
-
yield this._websocketController.watchBranchDevices(request.connectionId, data.recordName, data.inst, data.branch);
|
|
3013
|
-
}
|
|
3014
|
-
else if (data.type === 'repo/unwatch_branch_devices') {
|
|
3015
|
-
yield this._websocketController.unwatchBranchDevices(request.connectionId, data.recordName, data.inst, data.branch);
|
|
3016
|
-
}
|
|
3017
|
-
else if (data.type === 'repo/connection_count') {
|
|
3018
|
-
yield this._websocketController.deviceCount(request.connectionId, data.recordName, data.inst, data.branch);
|
|
3019
|
-
}
|
|
3020
|
-
else if (data.type === 'sync/time') {
|
|
3021
|
-
yield this._websocketController.syncTime(request.connectionId, data, Date.now());
|
|
3022
|
-
}
|
|
3023
|
-
else if (data.type === 'permission/request/missing') {
|
|
3024
|
-
yield this._websocketController.requestMissingPermission(request.connectionId, data);
|
|
3360
|
+
else {
|
|
3361
|
+
// not supported
|
|
3362
|
+
return;
|
|
3025
3363
|
}
|
|
3026
|
-
|
|
3027
|
-
|
|
3364
|
+
}
|
|
3365
|
+
}
|
|
3366
|
+
async _sendWebsocketZodError(connectionId, requestId, error) {
|
|
3367
|
+
await this._websocketController.sendError(connectionId, requestId, {
|
|
3368
|
+
success: false,
|
|
3369
|
+
errorCode: 'unacceptable_request',
|
|
3370
|
+
errorMessage: 'The request was invalid. One or more fields were invalid.',
|
|
3371
|
+
issues: error.issues,
|
|
3372
|
+
});
|
|
3373
|
+
}
|
|
3374
|
+
async _processWebsocketMessage(request, requestId, message) {
|
|
3375
|
+
const span = trace.getActiveSpan();
|
|
3376
|
+
const messageResult = websocketRequestMessageSchema.safeParse(message);
|
|
3377
|
+
if (messageResult.success === false) {
|
|
3378
|
+
span === null || span === void 0 ? void 0 : span.setAttribute('request.messageType', 'invalid');
|
|
3379
|
+
await this._sendWebsocketZodError(request.connectionId, requestId, messageResult.error);
|
|
3380
|
+
return;
|
|
3381
|
+
}
|
|
3382
|
+
const data = messageResult.data;
|
|
3383
|
+
span === null || span === void 0 ? void 0 : span.setAttribute('request.messageType', data.type);
|
|
3384
|
+
if (data.type === 'login') {
|
|
3385
|
+
await this._websocketController.login(request.connectionId, requestId, data);
|
|
3386
|
+
}
|
|
3387
|
+
else if (data.type === 'repo/watch_branch') {
|
|
3388
|
+
await this._websocketController.watchBranch(request.connectionId, data);
|
|
3389
|
+
}
|
|
3390
|
+
else if (data.type === 'repo/unwatch_branch') {
|
|
3391
|
+
await this._websocketController.unwatchBranch(request.connectionId, data.recordName, data.inst, data.branch);
|
|
3392
|
+
}
|
|
3393
|
+
else if (data.type === 'repo/add_updates') {
|
|
3394
|
+
await this._websocketController.addUpdates(request.connectionId, data);
|
|
3395
|
+
}
|
|
3396
|
+
else if (data.type === 'repo/get_updates') {
|
|
3397
|
+
await this._websocketController.getUpdates(request.connectionId, data.recordName, data.inst, data.branch);
|
|
3398
|
+
}
|
|
3399
|
+
else if (data.type === 'repo/send_action') {
|
|
3400
|
+
await this._websocketController.sendAction(request.connectionId, data);
|
|
3401
|
+
}
|
|
3402
|
+
else if (data.type === 'repo/watch_branch_devices') {
|
|
3403
|
+
await this._websocketController.watchBranchDevices(request.connectionId, data.recordName, data.inst, data.branch);
|
|
3404
|
+
}
|
|
3405
|
+
else if (data.type === 'repo/unwatch_branch_devices') {
|
|
3406
|
+
await this._websocketController.unwatchBranchDevices(request.connectionId, data.recordName, data.inst, data.branch);
|
|
3407
|
+
}
|
|
3408
|
+
else if (data.type === 'repo/connection_count') {
|
|
3409
|
+
await this._websocketController.deviceCount(request.connectionId, data.recordName, data.inst, data.branch);
|
|
3410
|
+
}
|
|
3411
|
+
else if (data.type === 'sync/time') {
|
|
3412
|
+
await this._websocketController.syncTime(request.connectionId, data, Date.now());
|
|
3413
|
+
}
|
|
3414
|
+
else if (data.type === 'permission/request/missing') {
|
|
3415
|
+
await this._websocketController.requestMissingPermission(request.connectionId, data);
|
|
3416
|
+
}
|
|
3417
|
+
else if (data.type === 'permission/request/missing/response') {
|
|
3418
|
+
await this._websocketController.respondToPermissionRequest(request.connectionId, data);
|
|
3419
|
+
}
|
|
3420
|
+
else if (data.type === 'http_request') {
|
|
3421
|
+
let headers = {};
|
|
3422
|
+
for (let key in data.request.headers) {
|
|
3423
|
+
headers[key.toLowerCase()] = data.request.headers[key];
|
|
3028
3424
|
}
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
const
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
const i = result.body[Symbol.asyncIterator]();
|
|
3050
|
-
while (true) {
|
|
3051
|
-
let { value, done } = yield i.next();
|
|
3052
|
-
yield this._websocketController.messenger.sendMessage([request.connectionId], {
|
|
3053
|
-
type: 'http_partial_response',
|
|
3054
|
-
id: data.id,
|
|
3055
|
-
index: index,
|
|
3056
|
-
final: done ? true : undefined,
|
|
3057
|
-
response: Object.assign(Object.assign({}, response), { body: value }),
|
|
3058
|
-
});
|
|
3059
|
-
response = {};
|
|
3060
|
-
index += 1;
|
|
3061
|
-
if (done) {
|
|
3062
|
-
break;
|
|
3063
|
-
}
|
|
3064
|
-
}
|
|
3065
|
-
}
|
|
3066
|
-
else {
|
|
3067
|
-
yield this._websocketController.messenger.sendMessage([request.connectionId], {
|
|
3068
|
-
type: 'http_response',
|
|
3425
|
+
headers.origin = request.origin;
|
|
3426
|
+
const httpRequest = {
|
|
3427
|
+
path: data.request.path,
|
|
3428
|
+
method: data.request.method,
|
|
3429
|
+
pathParams: data.request.pathParams,
|
|
3430
|
+
body: data.request.body,
|
|
3431
|
+
query: data.request.query,
|
|
3432
|
+
headers: headers,
|
|
3433
|
+
ipAddress: request.ipAddress,
|
|
3434
|
+
};
|
|
3435
|
+
const result = await this.handleHttpRequest(httpRequest);
|
|
3436
|
+
if (typeof result.body === 'object' &&
|
|
3437
|
+
Symbol.asyncIterator in result.body) {
|
|
3438
|
+
let response = result;
|
|
3439
|
+
let index = 0;
|
|
3440
|
+
const i = result.body[Symbol.asyncIterator]();
|
|
3441
|
+
while (true) {
|
|
3442
|
+
let { value, done } = await i.next();
|
|
3443
|
+
await this._websocketController.messenger.sendMessage([request.connectionId], {
|
|
3444
|
+
type: 'http_partial_response',
|
|
3069
3445
|
id: data.id,
|
|
3070
|
-
|
|
3446
|
+
index: index,
|
|
3447
|
+
final: done ? true : undefined,
|
|
3448
|
+
response: {
|
|
3449
|
+
...response,
|
|
3450
|
+
body: value,
|
|
3451
|
+
},
|
|
3071
3452
|
});
|
|
3453
|
+
response = {};
|
|
3454
|
+
index += 1;
|
|
3455
|
+
if (done) {
|
|
3456
|
+
break;
|
|
3457
|
+
}
|
|
3072
3458
|
}
|
|
3073
3459
|
}
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
const result = yield this._websocketController.downloadRequest(connectionId, requestId, url, method, headers);
|
|
3080
|
-
if (result.success === false) {
|
|
3081
|
-
yield this._websocketController.sendError(connectionId, requestId, result);
|
|
3082
|
-
return;
|
|
3083
|
-
}
|
|
3084
|
-
const parseResult = tryParseJson(result.message);
|
|
3085
|
-
if (!parseResult.success) {
|
|
3086
|
-
yield this._websocketController.sendError(connectionId, requestId, {
|
|
3087
|
-
success: false,
|
|
3088
|
-
errorCode: 'unacceptable_request',
|
|
3089
|
-
errorMessage: 'The request was invalid. The downloaded file must contain JSON.',
|
|
3460
|
+
else {
|
|
3461
|
+
await this._websocketController.messenger.sendMessage([request.connectionId], {
|
|
3462
|
+
type: 'http_response',
|
|
3463
|
+
id: data.id,
|
|
3464
|
+
response: result,
|
|
3090
3465
|
});
|
|
3091
|
-
return;
|
|
3092
3466
|
}
|
|
3093
|
-
|
|
3094
|
-
});
|
|
3467
|
+
}
|
|
3095
3468
|
}
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3469
|
+
async _processWebsocketDownload(request, requestId, url, method, headers) {
|
|
3470
|
+
const connectionId = request.connectionId;
|
|
3471
|
+
const result = await this._websocketController.downloadRequest(connectionId, requestId, url, method, headers);
|
|
3472
|
+
if (result.success === false) {
|
|
3473
|
+
await this._websocketController.sendError(connectionId, requestId, result);
|
|
3474
|
+
return;
|
|
3475
|
+
}
|
|
3476
|
+
const parseResult = tryParseJson(result.message);
|
|
3477
|
+
if (!parseResult.success) {
|
|
3478
|
+
await this._websocketController.sendError(connectionId, requestId, {
|
|
3479
|
+
success: false,
|
|
3480
|
+
errorCode: 'unacceptable_request',
|
|
3481
|
+
errorMessage: 'The request was invalid. The downloaded file must contain JSON.',
|
|
3482
|
+
});
|
|
3483
|
+
return;
|
|
3484
|
+
}
|
|
3485
|
+
await this._processWebsocketMessage(request, requestId, parseResult.value);
|
|
3486
|
+
}
|
|
3487
|
+
async _processWebsocketUploadRequest(request, requestId) {
|
|
3488
|
+
const connectionId = request.connectionId;
|
|
3489
|
+
await this._websocketController.uploadRequest(connectionId, requestId);
|
|
3101
3490
|
}
|
|
3102
3491
|
// private _setupRoutes() {
|
|
3103
3492
|
// this.addRoute({
|
|
@@ -5026,572 +5415,538 @@ export class RecordsServer {
|
|
|
5026
5415
|
// },
|
|
5027
5416
|
// });
|
|
5028
5417
|
// }
|
|
5029
|
-
_stripeWebhook(request) {
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5418
|
+
async _stripeWebhook(request) {
|
|
5419
|
+
if (!this._subscriptions) {
|
|
5420
|
+
return returnResult(SUBSCRIPTIONS_NOT_SUPPORTED_RESULT);
|
|
5421
|
+
}
|
|
5422
|
+
let body = null;
|
|
5423
|
+
if (typeof request.body === 'string') {
|
|
5424
|
+
body = request.body;
|
|
5425
|
+
}
|
|
5426
|
+
else if (ArrayBuffer.isView(request.body)) {
|
|
5427
|
+
try {
|
|
5428
|
+
const decoder = new TextDecoder();
|
|
5429
|
+
body = decoder.decode(request.body);
|
|
5037
5430
|
}
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
return returnResult({
|
|
5046
|
-
success: false,
|
|
5047
|
-
errorCode: 'invalid_request',
|
|
5048
|
-
errorMessage: INVALID_REQUEST_ERROR_MESSAGE,
|
|
5049
|
-
});
|
|
5050
|
-
}
|
|
5431
|
+
catch (err) {
|
|
5432
|
+
console.log('[RecordsServer] Unable to decode request body!', err);
|
|
5433
|
+
return returnResult({
|
|
5434
|
+
success: false,
|
|
5435
|
+
errorCode: 'invalid_request',
|
|
5436
|
+
errorMessage: INVALID_REQUEST_ERROR_MESSAGE,
|
|
5437
|
+
});
|
|
5051
5438
|
}
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
return returnResult(result);
|
|
5439
|
+
}
|
|
5440
|
+
const signature = request.headers['stripe-signature'];
|
|
5441
|
+
const result = await this._subscriptions.handleStripeWebhook({
|
|
5442
|
+
requestBody: body,
|
|
5443
|
+
signature,
|
|
5058
5444
|
});
|
|
5445
|
+
return returnResult(result);
|
|
5059
5446
|
}
|
|
5060
|
-
_handleOptions(request) {
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5447
|
+
async _handleOptions(request) {
|
|
5448
|
+
if (!validateOrigin(request, this._allowedApiOrigins)) {
|
|
5449
|
+
return returnResult(INVALID_ORIGIN_RESULT);
|
|
5450
|
+
}
|
|
5451
|
+
return {
|
|
5452
|
+
statusCode: 204,
|
|
5453
|
+
headers: {
|
|
5454
|
+
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
|
5455
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
|
5456
|
+
},
|
|
5457
|
+
};
|
|
5458
|
+
}
|
|
5459
|
+
async _handleRecordFileOptions(request) {
|
|
5460
|
+
if (!validateOrigin(request, this._allowedApiOrigins)) {
|
|
5461
|
+
return returnResult(INVALID_ORIGIN_RESULT);
|
|
5462
|
+
}
|
|
5463
|
+
const headers = this._files.getAllowedUploadHeaders();
|
|
5464
|
+
const allAllowedHeaders = new Set([
|
|
5465
|
+
...headers.map((h) => h.toLocaleLowerCase()),
|
|
5466
|
+
'content-type',
|
|
5467
|
+
'authorization',
|
|
5468
|
+
]);
|
|
5469
|
+
return {
|
|
5470
|
+
statusCode: 204,
|
|
5471
|
+
headers: {
|
|
5472
|
+
'Access-Control-Allow-Headers': [...allAllowedHeaders].join(', '),
|
|
5473
|
+
'Access-Control-Allow-Methods': 'POST',
|
|
5474
|
+
'Access-Control-Max-Age': '14400',
|
|
5475
|
+
},
|
|
5476
|
+
};
|
|
5477
|
+
}
|
|
5478
|
+
async _recordFile({ recordKey, fileSha256Hex, fileByteLength, fileMimeType, fileDescription, markers, instances, }, context) {
|
|
5479
|
+
if (!recordKey || typeof recordKey !== 'string') {
|
|
5065
5480
|
return {
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
|
5070
|
-
},
|
|
5481
|
+
success: false,
|
|
5482
|
+
errorCode: 'unacceptable_request',
|
|
5483
|
+
errorMessage: 'recordKey is required and must be a string.',
|
|
5071
5484
|
};
|
|
5072
|
-
}
|
|
5073
|
-
|
|
5074
|
-
_handleRecordFileOptions(request) {
|
|
5075
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
5076
|
-
if (!validateOrigin(request, this._allowedApiOrigins)) {
|
|
5077
|
-
return returnResult(INVALID_ORIGIN_RESULT);
|
|
5078
|
-
}
|
|
5079
|
-
const headers = this._files.getAllowedUploadHeaders();
|
|
5080
|
-
const allAllowedHeaders = new Set([
|
|
5081
|
-
...headers.map((h) => h.toLocaleLowerCase()),
|
|
5082
|
-
'content-type',
|
|
5083
|
-
'authorization',
|
|
5084
|
-
]);
|
|
5485
|
+
}
|
|
5486
|
+
if (!fileSha256Hex || typeof fileSha256Hex !== 'string') {
|
|
5085
5487
|
return {
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
'Access-Control-Allow-Methods': 'POST',
|
|
5090
|
-
'Access-Control-Max-Age': '14400',
|
|
5091
|
-
},
|
|
5488
|
+
success: false,
|
|
5489
|
+
errorCode: 'unacceptable_request',
|
|
5490
|
+
errorMessage: 'fileSha256Hex is required and must be a string.',
|
|
5092
5491
|
};
|
|
5492
|
+
}
|
|
5493
|
+
if (!fileByteLength || typeof fileByteLength !== 'number') {
|
|
5494
|
+
return {
|
|
5495
|
+
success: false,
|
|
5496
|
+
errorCode: 'unacceptable_request',
|
|
5497
|
+
errorMessage: 'fileByteLength is required and must be a number.',
|
|
5498
|
+
};
|
|
5499
|
+
}
|
|
5500
|
+
if (!fileMimeType || typeof fileMimeType !== 'string') {
|
|
5501
|
+
return {
|
|
5502
|
+
success: false,
|
|
5503
|
+
errorCode: 'unacceptable_request',
|
|
5504
|
+
errorMessage: 'fileMimeType is required and must be a string.',
|
|
5505
|
+
};
|
|
5506
|
+
}
|
|
5507
|
+
if (!!fileDescription && typeof fileDescription !== 'string') {
|
|
5508
|
+
return {
|
|
5509
|
+
success: false,
|
|
5510
|
+
errorCode: 'unacceptable_request',
|
|
5511
|
+
errorMessage: 'fileDescription must be a string.',
|
|
5512
|
+
};
|
|
5513
|
+
}
|
|
5514
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
5515
|
+
if (validation.success === false &&
|
|
5516
|
+
validation.errorCode !== 'no_session_key') {
|
|
5517
|
+
return validation;
|
|
5518
|
+
}
|
|
5519
|
+
const userId = validation.userId;
|
|
5520
|
+
const result = await this._files.recordFile(recordKey, userId, {
|
|
5521
|
+
fileSha256Hex,
|
|
5522
|
+
fileByteLength,
|
|
5523
|
+
fileMimeType,
|
|
5524
|
+
fileDescription,
|
|
5525
|
+
headers: {},
|
|
5526
|
+
markers,
|
|
5527
|
+
instances,
|
|
5093
5528
|
});
|
|
5529
|
+
return result;
|
|
5094
5530
|
}
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5531
|
+
async _updateFile(data, context) {
|
|
5532
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
5533
|
+
if (validation.success === false &&
|
|
5534
|
+
validation.errorCode !== 'no_session_key') {
|
|
5535
|
+
return validation;
|
|
5536
|
+
}
|
|
5537
|
+
const userId = validation.userId;
|
|
5538
|
+
const fileNameResult = await this._files.getFileNameFromUrl(data.fileUrl);
|
|
5539
|
+
if (!fileNameResult.success) {
|
|
5540
|
+
return fileNameResult;
|
|
5541
|
+
}
|
|
5542
|
+
const result = await this._files.updateFile(data.recordKey, fileNameResult.fileName, userId, data.markers, data.instances);
|
|
5543
|
+
return result;
|
|
5544
|
+
}
|
|
5545
|
+
async _readFile({ fileUrl, recordName, fileName, instances, }, context) {
|
|
5546
|
+
if (!!fileUrl && typeof fileUrl !== 'string') {
|
|
5547
|
+
return {
|
|
5548
|
+
success: false,
|
|
5549
|
+
errorCode: 'unacceptable_request',
|
|
5550
|
+
errorMessage: 'fileUrl must be a string.',
|
|
5551
|
+
};
|
|
5552
|
+
}
|
|
5553
|
+
if (!!recordName && typeof recordName !== 'string') {
|
|
5554
|
+
return {
|
|
5555
|
+
success: false,
|
|
5556
|
+
errorCode: 'unacceptable_request',
|
|
5557
|
+
errorMessage: 'recordName must be a string.',
|
|
5558
|
+
};
|
|
5559
|
+
}
|
|
5560
|
+
if (!!fileName && typeof fileName !== 'string') {
|
|
5561
|
+
return {
|
|
5562
|
+
success: false,
|
|
5563
|
+
errorCode: 'unacceptable_request',
|
|
5564
|
+
errorMessage: 'fileName must be a string.',
|
|
5565
|
+
};
|
|
5566
|
+
}
|
|
5567
|
+
if (!fileUrl && (!recordName || !fileName)) {
|
|
5568
|
+
let message;
|
|
5569
|
+
if (!!fileName) {
|
|
5570
|
+
message = 'recordName is required when fileName is provided.';
|
|
5131
5571
|
}
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
validation.errorCode !== 'no_session_key') {
|
|
5135
|
-
return validation;
|
|
5572
|
+
else if (!!recordName) {
|
|
5573
|
+
message = 'fileName is required when recordName is provided.';
|
|
5136
5574
|
}
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
fileByteLength,
|
|
5141
|
-
fileMimeType,
|
|
5142
|
-
fileDescription,
|
|
5143
|
-
headers: {},
|
|
5144
|
-
markers,
|
|
5145
|
-
instances,
|
|
5146
|
-
});
|
|
5147
|
-
return result;
|
|
5148
|
-
});
|
|
5149
|
-
}
|
|
5150
|
-
_updateFile(data, context) {
|
|
5151
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
5152
|
-
const validation = yield this._validateSessionKey(context.sessionKey);
|
|
5153
|
-
if (validation.success === false &&
|
|
5154
|
-
validation.errorCode !== 'no_session_key') {
|
|
5155
|
-
return validation;
|
|
5575
|
+
else {
|
|
5576
|
+
message =
|
|
5577
|
+
'fileUrl or both recordName and fileName are required.';
|
|
5156
5578
|
}
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5579
|
+
return {
|
|
5580
|
+
success: false,
|
|
5581
|
+
errorCode: 'unacceptable_request',
|
|
5582
|
+
errorMessage: message,
|
|
5583
|
+
};
|
|
5584
|
+
}
|
|
5585
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
5586
|
+
if (validation.success === false &&
|
|
5587
|
+
validation.errorCode !== 'no_session_key') {
|
|
5588
|
+
return validation;
|
|
5589
|
+
}
|
|
5590
|
+
const userId = validation.userId;
|
|
5591
|
+
if (!!fileUrl) {
|
|
5592
|
+
const fileNameResult = await this._files.getFileNameFromUrl(fileUrl);
|
|
5593
|
+
if (fileNameResult.success === false) {
|
|
5160
5594
|
return fileNameResult;
|
|
5161
5595
|
}
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
}
|
|
5596
|
+
recordName = fileNameResult.recordName;
|
|
5597
|
+
fileName = fileNameResult.fileName;
|
|
5598
|
+
}
|
|
5599
|
+
const result = await this._files.readFile(recordName, fileName, userId, instances);
|
|
5600
|
+
return result;
|
|
5165
5601
|
}
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
if (!fileUrl && (!recordName || !fileName)) {
|
|
5190
|
-
let message;
|
|
5191
|
-
if (!!fileName) {
|
|
5192
|
-
message = 'recordName is required when fileName is provided.';
|
|
5193
|
-
}
|
|
5194
|
-
else if (!!recordName) {
|
|
5195
|
-
message = 'fileName is required when recordName is provided.';
|
|
5196
|
-
}
|
|
5197
|
-
else {
|
|
5198
|
-
message =
|
|
5199
|
-
'fileUrl or both recordName and fileName are required.';
|
|
5200
|
-
}
|
|
5201
|
-
return {
|
|
5202
|
-
success: false,
|
|
5203
|
-
errorCode: 'unacceptable_request',
|
|
5204
|
-
errorMessage: message,
|
|
5205
|
-
};
|
|
5206
|
-
}
|
|
5207
|
-
const validation = yield this._validateSessionKey(context.sessionKey);
|
|
5208
|
-
if (validation.success === false &&
|
|
5209
|
-
validation.errorCode !== 'no_session_key') {
|
|
5210
|
-
return validation;
|
|
5211
|
-
}
|
|
5212
|
-
const userId = validation.userId;
|
|
5213
|
-
if (!!fileUrl) {
|
|
5214
|
-
const fileNameResult = yield this._files.getFileNameFromUrl(fileUrl);
|
|
5215
|
-
if (fileNameResult.success === false) {
|
|
5216
|
-
return fileNameResult;
|
|
5217
|
-
}
|
|
5218
|
-
recordName = fileNameResult.recordName;
|
|
5219
|
-
fileName = fileNameResult.fileName;
|
|
5220
|
-
}
|
|
5221
|
-
const result = yield this._files.readFile(recordName, fileName, userId, instances);
|
|
5222
|
-
return result;
|
|
5223
|
-
});
|
|
5602
|
+
async _listFiles({ recordName, fileName, instances }, context) {
|
|
5603
|
+
if (!!recordName && typeof recordName !== 'string') {
|
|
5604
|
+
return {
|
|
5605
|
+
success: false,
|
|
5606
|
+
errorCode: 'unacceptable_request',
|
|
5607
|
+
errorMessage: 'recordName must be a string.',
|
|
5608
|
+
};
|
|
5609
|
+
}
|
|
5610
|
+
if (!!fileName && typeof fileName !== 'string') {
|
|
5611
|
+
return {
|
|
5612
|
+
success: false,
|
|
5613
|
+
errorCode: 'unacceptable_request',
|
|
5614
|
+
errorMessage: 'fileName must be a string.',
|
|
5615
|
+
};
|
|
5616
|
+
}
|
|
5617
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
5618
|
+
if (validation.success === false &&
|
|
5619
|
+
validation.errorCode !== 'no_session_key') {
|
|
5620
|
+
return validation;
|
|
5621
|
+
}
|
|
5622
|
+
const userId = validation.userId;
|
|
5623
|
+
const result = await this._files.listFiles(recordName, fileName, userId, instances);
|
|
5624
|
+
return result;
|
|
5224
5625
|
}
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
return
|
|
5249
|
-
}
|
|
5626
|
+
async _eraseFile({ recordKey, fileUrl, instances }, context) {
|
|
5627
|
+
if (!recordKey || typeof recordKey !== 'string') {
|
|
5628
|
+
return {
|
|
5629
|
+
success: false,
|
|
5630
|
+
errorCode: 'unacceptable_request',
|
|
5631
|
+
errorMessage: 'recordKey is required and must be a string.',
|
|
5632
|
+
};
|
|
5633
|
+
}
|
|
5634
|
+
if (!fileUrl || typeof fileUrl !== 'string') {
|
|
5635
|
+
return {
|
|
5636
|
+
success: false,
|
|
5637
|
+
errorCode: 'unacceptable_request',
|
|
5638
|
+
errorMessage: 'fileUrl is required and must be a string.',
|
|
5639
|
+
};
|
|
5640
|
+
}
|
|
5641
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
5642
|
+
if (validation.success === false &&
|
|
5643
|
+
validation.errorCode !== 'no_session_key') {
|
|
5644
|
+
return validation;
|
|
5645
|
+
}
|
|
5646
|
+
const userId = validation.userId;
|
|
5647
|
+
const fileNameResult = await this._files.getFileNameFromUrl(fileUrl);
|
|
5648
|
+
if (!fileNameResult.success) {
|
|
5649
|
+
return fileNameResult;
|
|
5650
|
+
}
|
|
5651
|
+
const result = await this._files.eraseFile(recordKey, fileNameResult.fileName, userId, instances);
|
|
5652
|
+
return result;
|
|
5250
5653
|
}
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
}
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5654
|
+
async _baseRecordData(controller, { recordKey, address, data, updatePolicy, deletePolicy, markers, instances, }, context) {
|
|
5655
|
+
if (!recordKey || typeof recordKey !== 'string') {
|
|
5656
|
+
return {
|
|
5657
|
+
success: false,
|
|
5658
|
+
errorCode: 'unacceptable_request',
|
|
5659
|
+
errorMessage: 'recordKey is required and must be a string.',
|
|
5660
|
+
};
|
|
5661
|
+
}
|
|
5662
|
+
if (!address || typeof address !== 'string') {
|
|
5663
|
+
return {
|
|
5664
|
+
success: false,
|
|
5665
|
+
errorCode: 'unacceptable_request',
|
|
5666
|
+
errorMessage: 'address is required and must be a string.',
|
|
5667
|
+
};
|
|
5668
|
+
}
|
|
5669
|
+
if (typeof data === 'undefined') {
|
|
5670
|
+
return {
|
|
5671
|
+
success: false,
|
|
5672
|
+
errorCode: 'unacceptable_request',
|
|
5673
|
+
errorMessage: 'data is required.',
|
|
5674
|
+
};
|
|
5675
|
+
}
|
|
5676
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
5677
|
+
if (validation.success === false &&
|
|
5678
|
+
validation.errorCode !== 'no_session_key') {
|
|
5679
|
+
return validation;
|
|
5680
|
+
}
|
|
5681
|
+
const userId = validation.userId;
|
|
5682
|
+
const result = await controller.recordData(recordKey, address, data, userId, updatePolicy, deletePolicy, markers, instances);
|
|
5683
|
+
return result;
|
|
5280
5684
|
}
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
}
|
|
5304
|
-
const validation = yield this._validateSessionKey(context.sessionKey);
|
|
5305
|
-
if (validation.success === false &&
|
|
5306
|
-
validation.errorCode !== 'no_session_key') {
|
|
5307
|
-
return validation;
|
|
5308
|
-
}
|
|
5309
|
-
const userId = validation.userId;
|
|
5310
|
-
const result = yield controller.recordData(recordKey, address, data, userId, updatePolicy, deletePolicy, markers, instances);
|
|
5311
|
-
return result;
|
|
5312
|
-
});
|
|
5685
|
+
async _baseGetRecordData(controller, { recordName, address, instances }, context) {
|
|
5686
|
+
if (!recordName || typeof recordName !== 'string') {
|
|
5687
|
+
return {
|
|
5688
|
+
success: false,
|
|
5689
|
+
errorCode: 'unacceptable_request',
|
|
5690
|
+
errorMessage: 'recordName is required and must be a string.',
|
|
5691
|
+
};
|
|
5692
|
+
}
|
|
5693
|
+
if (!address || typeof address !== 'string') {
|
|
5694
|
+
return {
|
|
5695
|
+
success: false,
|
|
5696
|
+
errorCode: 'unacceptable_request',
|
|
5697
|
+
errorMessage: 'address is required and must be a string.',
|
|
5698
|
+
};
|
|
5699
|
+
}
|
|
5700
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
5701
|
+
if (validation.success === false &&
|
|
5702
|
+
validation.errorCode !== 'no_session_key') {
|
|
5703
|
+
return validation;
|
|
5704
|
+
}
|
|
5705
|
+
const result = await controller.getData(recordName, address, validation.userId, instances);
|
|
5706
|
+
return result;
|
|
5313
5707
|
}
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
});
|
|
5708
|
+
async _baseEraseRecordData(controller, { recordKey, address, instances }, context) {
|
|
5709
|
+
if (!recordKey || typeof recordKey !== 'string') {
|
|
5710
|
+
return {
|
|
5711
|
+
success: false,
|
|
5712
|
+
errorCode: 'unacceptable_request',
|
|
5713
|
+
errorMessage: 'recordKey is required and must be a string.',
|
|
5714
|
+
};
|
|
5715
|
+
}
|
|
5716
|
+
if (!address || typeof address !== 'string') {
|
|
5717
|
+
return {
|
|
5718
|
+
success: false,
|
|
5719
|
+
errorCode: 'unacceptable_request',
|
|
5720
|
+
errorMessage: 'address is required and must be a string.',
|
|
5721
|
+
};
|
|
5722
|
+
}
|
|
5723
|
+
const validation = await this._validateSessionKey(context.sessionKey);
|
|
5724
|
+
if (validation.success === false &&
|
|
5725
|
+
validation.errorCode !== 'no_session_key') {
|
|
5726
|
+
return validation;
|
|
5727
|
+
}
|
|
5728
|
+
const userId = validation.userId;
|
|
5729
|
+
const result = await controller.eraseData(recordKey, address, userId, instances);
|
|
5730
|
+
return result;
|
|
5338
5731
|
}
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
}
|
|
5348
|
-
if (!address || typeof address !== 'string') {
|
|
5349
|
-
return {
|
|
5350
|
-
success: false,
|
|
5351
|
-
errorCode: 'unacceptable_request',
|
|
5352
|
-
errorMessage: 'address is required and must be a string.',
|
|
5353
|
-
};
|
|
5354
|
-
}
|
|
5355
|
-
const validation = yield this._validateSessionKey(context.sessionKey);
|
|
5356
|
-
if (validation.success === false &&
|
|
5357
|
-
validation.errorCode !== 'no_session_key') {
|
|
5358
|
-
return validation;
|
|
5359
|
-
}
|
|
5360
|
-
const userId = validation.userId;
|
|
5361
|
-
const result = yield controller.eraseData(recordKey, address, userId, instances);
|
|
5362
|
-
return result;
|
|
5732
|
+
async _postReplaceSession(request) {
|
|
5733
|
+
const sessionKey = getSessionKey(request);
|
|
5734
|
+
if (!sessionKey) {
|
|
5735
|
+
return returnResult(NOT_LOGGED_IN_RESULT);
|
|
5736
|
+
}
|
|
5737
|
+
const result = await this._auth.replaceSession({
|
|
5738
|
+
sessionKey: sessionKey,
|
|
5739
|
+
ipAddress: request.ipAddress,
|
|
5363
5740
|
});
|
|
5741
|
+
return returnResult(result);
|
|
5364
5742
|
}
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5743
|
+
async _getSubscriptionInfo(request) {
|
|
5744
|
+
if (!this._subscriptions) {
|
|
5745
|
+
return returnResult(SUBSCRIPTIONS_NOT_SUPPORTED_RESULT);
|
|
5746
|
+
}
|
|
5747
|
+
if (!validateOrigin(request, this._allowedAccountOrigins)) {
|
|
5748
|
+
return returnResult(INVALID_ORIGIN_RESULT);
|
|
5749
|
+
}
|
|
5750
|
+
const sessionKey = getSessionKey(request);
|
|
5751
|
+
if (!sessionKey) {
|
|
5752
|
+
return returnResult(NOT_LOGGED_IN_RESULT);
|
|
5753
|
+
}
|
|
5754
|
+
const userId = tryDecodeUriComponent(request.pathParams.userId);
|
|
5755
|
+
if (!userId) {
|
|
5756
|
+
return returnResult(UNACCEPTABLE_USER_ID);
|
|
5757
|
+
}
|
|
5758
|
+
const result = await this._subscriptions.getSubscriptionStatus({
|
|
5759
|
+
sessionKey,
|
|
5760
|
+
userId,
|
|
5376
5761
|
});
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
productName: s.productName,
|
|
5408
|
-
startDate: s.startDate,
|
|
5409
|
-
endedDate: s.endedDate,
|
|
5410
|
-
cancelDate: s.cancelDate,
|
|
5411
|
-
canceledDate: s.canceledDate,
|
|
5412
|
-
currentPeriodStart: s.currentPeriodStart,
|
|
5413
|
-
currentPeriodEnd: s.currentPeriodEnd,
|
|
5414
|
-
renewalInterval: s.renewalInterval,
|
|
5415
|
-
intervalLength: s.intervalLength,
|
|
5416
|
-
intervalCost: s.intervalCost,
|
|
5417
|
-
currency: s.currency,
|
|
5418
|
-
featureList: s.featureList,
|
|
5419
|
-
})),
|
|
5420
|
-
purchasableSubscriptions: result.purchasableSubscriptions.map((s) => ({
|
|
5421
|
-
id: s.id,
|
|
5422
|
-
name: s.name,
|
|
5423
|
-
description: s.description,
|
|
5424
|
-
featureList: s.featureList,
|
|
5425
|
-
prices: s.prices,
|
|
5426
|
-
defaultSubscription: s.defaultSubscription,
|
|
5427
|
-
})),
|
|
5428
|
-
});
|
|
5762
|
+
if (!result.success) {
|
|
5763
|
+
return returnResult(result);
|
|
5764
|
+
}
|
|
5765
|
+
return returnResult({
|
|
5766
|
+
success: true,
|
|
5767
|
+
publishableKey: result.publishableKey,
|
|
5768
|
+
subscriptions: result.subscriptions.map((s) => ({
|
|
5769
|
+
active: s.active,
|
|
5770
|
+
statusCode: s.statusCode,
|
|
5771
|
+
productName: s.productName,
|
|
5772
|
+
startDate: s.startDate,
|
|
5773
|
+
endedDate: s.endedDate,
|
|
5774
|
+
cancelDate: s.cancelDate,
|
|
5775
|
+
canceledDate: s.canceledDate,
|
|
5776
|
+
currentPeriodStart: s.currentPeriodStart,
|
|
5777
|
+
currentPeriodEnd: s.currentPeriodEnd,
|
|
5778
|
+
renewalInterval: s.renewalInterval,
|
|
5779
|
+
intervalLength: s.intervalLength,
|
|
5780
|
+
intervalCost: s.intervalCost,
|
|
5781
|
+
currency: s.currency,
|
|
5782
|
+
featureList: s.featureList,
|
|
5783
|
+
})),
|
|
5784
|
+
purchasableSubscriptions: result.purchasableSubscriptions.map((s) => ({
|
|
5785
|
+
id: s.id,
|
|
5786
|
+
name: s.name,
|
|
5787
|
+
description: s.description,
|
|
5788
|
+
featureList: s.featureList,
|
|
5789
|
+
prices: s.prices,
|
|
5790
|
+
defaultSubscription: s.defaultSubscription,
|
|
5791
|
+
})),
|
|
5429
5792
|
});
|
|
5430
5793
|
}
|
|
5431
|
-
_manageSubscription(request) {
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
expectedPrice
|
|
5472
|
-
.expectedPrice;
|
|
5473
|
-
}
|
|
5794
|
+
async _manageSubscription(request) {
|
|
5795
|
+
if (!this._subscriptions) {
|
|
5796
|
+
return returnResult(SUBSCRIPTIONS_NOT_SUPPORTED_RESULT);
|
|
5797
|
+
}
|
|
5798
|
+
if (!validateOrigin(request, this._allowedAccountOrigins)) {
|
|
5799
|
+
return returnResult(INVALID_ORIGIN_RESULT);
|
|
5800
|
+
}
|
|
5801
|
+
const sessionKey = getSessionKey(request);
|
|
5802
|
+
if (!sessionKey) {
|
|
5803
|
+
return returnResult(NOT_LOGGED_IN_RESULT);
|
|
5804
|
+
}
|
|
5805
|
+
const userId = tryDecodeUriComponent(request.pathParams.userId);
|
|
5806
|
+
if (!userId) {
|
|
5807
|
+
return returnResult(UNACCEPTABLE_USER_ID);
|
|
5808
|
+
}
|
|
5809
|
+
let subscriptionId;
|
|
5810
|
+
let expectedPrice;
|
|
5811
|
+
if (typeof request.body === 'string' && request.body) {
|
|
5812
|
+
let body = tryParseJson(request.body);
|
|
5813
|
+
if (body.success) {
|
|
5814
|
+
const schema = z.object({
|
|
5815
|
+
subscriptionId: z.string().optional(),
|
|
5816
|
+
expectedPrice: z
|
|
5817
|
+
.object({
|
|
5818
|
+
currency: z.string(),
|
|
5819
|
+
cost: z.number(),
|
|
5820
|
+
interval: z.enum(['month', 'year', 'week', 'day']),
|
|
5821
|
+
intervalLength: z.number(),
|
|
5822
|
+
})
|
|
5823
|
+
.optional(),
|
|
5824
|
+
});
|
|
5825
|
+
const parseResult = schema.safeParse(body.value);
|
|
5826
|
+
if (parseResult.success === false) {
|
|
5827
|
+
return returnZodError(parseResult.error);
|
|
5828
|
+
}
|
|
5829
|
+
if (typeof parseResult.data.subscriptionId === 'string') {
|
|
5830
|
+
subscriptionId = parseResult.data.subscriptionId;
|
|
5831
|
+
}
|
|
5832
|
+
if (typeof parseResult.data.expectedPrice === 'object') {
|
|
5833
|
+
expectedPrice = parseResult.data
|
|
5834
|
+
.expectedPrice;
|
|
5474
5835
|
}
|
|
5475
5836
|
}
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5837
|
+
}
|
|
5838
|
+
const result = await this._subscriptions.createManageSubscriptionLink({
|
|
5839
|
+
sessionKey,
|
|
5840
|
+
userId,
|
|
5841
|
+
subscriptionId,
|
|
5842
|
+
expectedPrice,
|
|
5843
|
+
});
|
|
5844
|
+
if (!result.success) {
|
|
5845
|
+
return returnResult(result);
|
|
5846
|
+
}
|
|
5847
|
+
return returnResult({
|
|
5848
|
+
success: true,
|
|
5849
|
+
url: result.url,
|
|
5489
5850
|
});
|
|
5490
5851
|
}
|
|
5491
5852
|
/**
|
|
5492
5853
|
* Endpoint to retrieve info about a user.
|
|
5493
5854
|
* @param request The request.
|
|
5494
5855
|
*/
|
|
5495
|
-
_getUserInfo(request) {
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
userId,
|
|
5514
|
-
});
|
|
5515
|
-
if (!result.success) {
|
|
5516
|
-
return returnResult(result);
|
|
5517
|
-
}
|
|
5518
|
-
return returnResult({
|
|
5519
|
-
success: true,
|
|
5520
|
-
name: result.name,
|
|
5521
|
-
avatarUrl: result.avatarUrl,
|
|
5522
|
-
avatarPortraitUrl: result.avatarPortraitUrl,
|
|
5523
|
-
email: result.email,
|
|
5524
|
-
phoneNumber: result.phoneNumber,
|
|
5525
|
-
hasActiveSubscription: result.hasActiveSubscription,
|
|
5526
|
-
subscriptionTier: result.subscriptionTier,
|
|
5527
|
-
privacyFeatures: result.privacyFeatures,
|
|
5528
|
-
displayName: result.displayName,
|
|
5529
|
-
role: result.role,
|
|
5530
|
-
});
|
|
5856
|
+
async _getUserInfo(request) {
|
|
5857
|
+
if (request.method !== 'GET') {
|
|
5858
|
+
throw new Error(`getUserInfo only accept GET method, you tried: ${request.method}`);
|
|
5859
|
+
}
|
|
5860
|
+
if (!validateOrigin(request, this._allowedAccountOrigins)) {
|
|
5861
|
+
return returnResult(INVALID_ORIGIN_RESULT);
|
|
5862
|
+
}
|
|
5863
|
+
const sessionKey = getSessionKey(request);
|
|
5864
|
+
if (!sessionKey) {
|
|
5865
|
+
return returnResult(NOT_LOGGED_IN_RESULT);
|
|
5866
|
+
}
|
|
5867
|
+
const userId = tryDecodeUriComponent(request.pathParams.userId);
|
|
5868
|
+
if (!userId) {
|
|
5869
|
+
return returnResult(UNACCEPTABLE_USER_ID);
|
|
5870
|
+
}
|
|
5871
|
+
const result = await this._auth.getUserInfo({
|
|
5872
|
+
sessionKey,
|
|
5873
|
+
userId,
|
|
5531
5874
|
});
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
}
|
|
5548
|
-
const jsonResult = tryParseJson(request.body);
|
|
5549
|
-
if (!jsonResult.success || typeof jsonResult.value !== 'object') {
|
|
5550
|
-
return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
|
|
5551
|
-
}
|
|
5552
|
-
const userId = tryDecodeUriComponent(request.pathParams.userId);
|
|
5553
|
-
if (!userId) {
|
|
5554
|
-
return returnResult(UNACCEPTABLE_USER_ID);
|
|
5555
|
-
}
|
|
5556
|
-
const schema = z.object({
|
|
5557
|
-
name: z.string().min(1).optional().nullable(),
|
|
5558
|
-
email: z
|
|
5559
|
-
.string()
|
|
5560
|
-
.email()
|
|
5561
|
-
.max(MAX_EMAIL_ADDRESS_LENGTH)
|
|
5562
|
-
.optional()
|
|
5563
|
-
.nullable(),
|
|
5564
|
-
phoneNumber: z
|
|
5565
|
-
.string()
|
|
5566
|
-
.max(MAX_SMS_ADDRESS_LENGTH)
|
|
5567
|
-
.optional()
|
|
5568
|
-
.nullable(),
|
|
5569
|
-
avatarUrl: z.string().url().optional().nullable(),
|
|
5570
|
-
avatarPortraitUrl: z.string().url().optional().nullable(),
|
|
5571
|
-
});
|
|
5572
|
-
const parseResult = schema.safeParse(jsonResult.value);
|
|
5573
|
-
if (parseResult.success === false) {
|
|
5574
|
-
return returnZodError(parseResult.error);
|
|
5575
|
-
}
|
|
5576
|
-
const update = parseResult.data;
|
|
5577
|
-
const result = yield this._auth.updateUserInfo({
|
|
5578
|
-
sessionKey: sessionKey,
|
|
5579
|
-
userId: userId,
|
|
5580
|
-
update,
|
|
5581
|
-
});
|
|
5582
|
-
if (!result.success) {
|
|
5583
|
-
return returnResult(result);
|
|
5584
|
-
}
|
|
5585
|
-
return returnResult({
|
|
5586
|
-
success: true,
|
|
5587
|
-
userId: result.userId,
|
|
5588
|
-
});
|
|
5875
|
+
if (!result.success) {
|
|
5876
|
+
return returnResult(result);
|
|
5877
|
+
}
|
|
5878
|
+
return returnResult({
|
|
5879
|
+
success: true,
|
|
5880
|
+
name: result.name,
|
|
5881
|
+
avatarUrl: result.avatarUrl,
|
|
5882
|
+
avatarPortraitUrl: result.avatarPortraitUrl,
|
|
5883
|
+
email: result.email,
|
|
5884
|
+
phoneNumber: result.phoneNumber,
|
|
5885
|
+
hasActiveSubscription: result.hasActiveSubscription,
|
|
5886
|
+
subscriptionTier: result.subscriptionTier,
|
|
5887
|
+
privacyFeatures: result.privacyFeatures,
|
|
5888
|
+
displayName: result.displayName,
|
|
5889
|
+
role: result.role,
|
|
5589
5890
|
});
|
|
5590
5891
|
}
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5892
|
+
async _putUserInfo(request) {
|
|
5893
|
+
if (request.method !== 'PUT') {
|
|
5894
|
+
throw new Error(`putUserInfo only accept PUT method, you tried: ${request.method}`);
|
|
5895
|
+
}
|
|
5896
|
+
if (!validateOrigin(request, this._allowedAccountOrigins)) {
|
|
5897
|
+
return returnResult(INVALID_ORIGIN_RESULT);
|
|
5898
|
+
}
|
|
5899
|
+
const sessionKey = getSessionKey(request);
|
|
5900
|
+
if (!sessionKey) {
|
|
5901
|
+
return returnResult(NOT_LOGGED_IN_RESULT);
|
|
5902
|
+
}
|
|
5903
|
+
if (typeof request.body !== 'string') {
|
|
5904
|
+
return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
|
|
5905
|
+
}
|
|
5906
|
+
const jsonResult = tryParseJson(request.body);
|
|
5907
|
+
if (!jsonResult.success || typeof jsonResult.value !== 'object') {
|
|
5908
|
+
return returnResult(UNACCEPTABLE_REQUEST_RESULT_MUST_BE_JSON);
|
|
5909
|
+
}
|
|
5910
|
+
const userId = tryDecodeUriComponent(request.pathParams.userId);
|
|
5911
|
+
if (!userId) {
|
|
5912
|
+
return returnResult(UNACCEPTABLE_USER_ID);
|
|
5913
|
+
}
|
|
5914
|
+
const schema = z.object({
|
|
5915
|
+
name: z.string().min(1).optional().nullable(),
|
|
5916
|
+
email: z
|
|
5917
|
+
.string()
|
|
5918
|
+
.email()
|
|
5919
|
+
.max(MAX_EMAIL_ADDRESS_LENGTH)
|
|
5920
|
+
.optional()
|
|
5921
|
+
.nullable(),
|
|
5922
|
+
phoneNumber: z
|
|
5923
|
+
.string()
|
|
5924
|
+
.max(MAX_SMS_ADDRESS_LENGTH)
|
|
5925
|
+
.optional()
|
|
5926
|
+
.nullable(),
|
|
5927
|
+
avatarUrl: z.string().url().optional().nullable(),
|
|
5928
|
+
avatarPortraitUrl: z.string().url().optional().nullable(),
|
|
5594
5929
|
});
|
|
5930
|
+
const parseResult = schema.safeParse(jsonResult.value);
|
|
5931
|
+
if (parseResult.success === false) {
|
|
5932
|
+
return returnZodError(parseResult.error);
|
|
5933
|
+
}
|
|
5934
|
+
const update = parseResult.data;
|
|
5935
|
+
const result = await this._auth.updateUserInfo({
|
|
5936
|
+
sessionKey: sessionKey,
|
|
5937
|
+
userId: userId,
|
|
5938
|
+
update,
|
|
5939
|
+
});
|
|
5940
|
+
if (!result.success) {
|
|
5941
|
+
return returnResult(result);
|
|
5942
|
+
}
|
|
5943
|
+
return returnResult({
|
|
5944
|
+
success: true,
|
|
5945
|
+
userId: result.userId,
|
|
5946
|
+
});
|
|
5947
|
+
}
|
|
5948
|
+
async _validateSessionKey(sessionKey) {
|
|
5949
|
+
return validateSessionKey(this._auth, sessionKey);
|
|
5595
5950
|
}
|
|
5596
5951
|
}
|
|
5597
5952
|
__decorate([
|
|
@@ -5686,16 +6041,14 @@ export function returnProcedureOutputStream(result) {
|
|
|
5686
6041
|
['result.stream']: true,
|
|
5687
6042
|
});
|
|
5688
6043
|
}
|
|
5689
|
-
function generateBody() {
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
return yield __await(JSON.stringify(value));
|
|
5695
|
-
}
|
|
5696
|
-
yield yield __await(JSON.stringify(value) + '\n');
|
|
6044
|
+
async function* generateBody() {
|
|
6045
|
+
while (true) {
|
|
6046
|
+
const { done, value } = await result.next();
|
|
6047
|
+
if (done) {
|
|
6048
|
+
return JSON.stringify(value);
|
|
5697
6049
|
}
|
|
5698
|
-
|
|
6050
|
+
yield JSON.stringify(value) + '\n';
|
|
6051
|
+
}
|
|
5699
6052
|
}
|
|
5700
6053
|
return {
|
|
5701
6054
|
statusCode: 200,
|
|
@@ -5749,7 +6102,9 @@ export function parseAuthorization(authorization) {
|
|
|
5749
6102
|
}
|
|
5750
6103
|
export function formatResponse(request, response, origins) {
|
|
5751
6104
|
const origin = request.headers['origin'];
|
|
5752
|
-
let headers =
|
|
6105
|
+
let headers = {
|
|
6106
|
+
...(response.headers || {}),
|
|
6107
|
+
};
|
|
5753
6108
|
if (!!origin &&
|
|
5754
6109
|
(origins === true ||
|
|
5755
6110
|
(typeof origins === 'object' && validateOrigin(request, origins)))) {
|
|
@@ -5761,13 +6116,16 @@ export function formatResponse(request, response, origins) {
|
|
|
5761
6116
|
'Content-Type, Authorization';
|
|
5762
6117
|
}
|
|
5763
6118
|
}
|
|
5764
|
-
return
|
|
6119
|
+
return {
|
|
6120
|
+
...response,
|
|
6121
|
+
headers,
|
|
6122
|
+
};
|
|
5765
6123
|
}
|
|
5766
6124
|
export function wrapHandler(func, allowedOrigins) {
|
|
5767
|
-
return (request) =>
|
|
5768
|
-
const response =
|
|
6125
|
+
return async (request) => {
|
|
6126
|
+
const response = await func(request);
|
|
5769
6127
|
return formatResponse(request, response, allowedOrigins);
|
|
5770
|
-
}
|
|
6128
|
+
};
|
|
5771
6129
|
}
|
|
5772
6130
|
/**
|
|
5773
6131
|
* Returns the given ZodError as a GenericHttpResponse.
|