@liveblocks/node 1.0.2 → 1.0.6-test2

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/README.md CHANGED
@@ -32,8 +32,9 @@ npm install @liveblocks/node
32
32
 
33
33
  ## Documentation
34
34
 
35
- Read the [documentation](https://liveblocks.io/docs) for guides and API
36
- references.
35
+ Read the
36
+ [documentation](https://liveblocks.io/docs/api-reference/liveblocks-node) for
37
+ guides and API references.
37
38
 
38
39
  ## Examples
39
40
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,55 @@
1
1
  import { IncomingHttpHeaders } from 'http';
2
2
 
3
+ declare type AuthorizeOptions = {
4
+ /**
5
+ * The secret api provided at https://liveblocks.io/dashboard/apikeys
6
+ */
7
+ secret: string;
8
+ /**
9
+ * The room provided in the authorization request body
10
+ */
11
+ room: string;
12
+ /**
13
+ * The id of the user that try to connect. It can be used to get information about the connected users in the room (name, avatar, etc).
14
+ * It can also be used to generate a token that gives access to a private room where the userId is configured in the room accesses.
15
+ * Liveblocks uses the userId to calculate your account's Monthly Active Users.
16
+ */
17
+ userId: string;
18
+ /**
19
+ * The info associated to the user. Can be used to store the name or the profile picture to implement avatar for example. Can't exceed 1KB when serialized as JSON
20
+ */
21
+ userInfo?: unknown;
22
+ /**
23
+ * The ids of the groups to which the user belongs. It should be used to generate a token that gives access to a private room and at least one of the group is configured in the room accesses.
24
+ */
25
+ groupIds?: string[];
26
+ };
27
+ declare type AuthorizeResponse = {
28
+ status: number;
29
+ body: string;
30
+ error?: Error;
31
+ };
32
+ /**
33
+ * @example
34
+ * export default async function auth(req, res) {
35
+ *
36
+ * // Implement your own security here.
37
+ *
38
+ * const room = req.body.room;
39
+ * const response = await authorize({
40
+ * room,
41
+ * secret,
42
+ * userId: "123",
43
+ * userInfo: { // Optional
44
+ * name: "Ada Lovelace"
45
+ * },
46
+ * groupIds: ["group1"] // Optional
47
+ * });
48
+ * return res.status(response.status).end(response.body);
49
+ * }
50
+ */
51
+ declare function authorize(options: AuthorizeOptions): Promise<AuthorizeResponse>;
52
+
3
53
  declare class WebhookHandler {
4
54
  private secretBuffer;
5
55
  private static secretPrefix;
@@ -122,54 +172,4 @@ declare type RoomDeletedEvent = {
122
172
  };
123
173
  };
124
174
 
125
- declare type AuthorizeOptions = {
126
- /**
127
- * The secret api provided at https://liveblocks.io/dashboard/apikeys
128
- */
129
- secret: string;
130
- /**
131
- * The room provided in the authorization request body
132
- */
133
- room: string;
134
- /**
135
- * The id of the user that try to connect. It can be used to get information about the connected users in the room (name, avatar, etc).
136
- * It can also be used to generate a token that gives access to a private room where the userId is configured in the room accesses.
137
- * Liveblocks uses the userId to calculate your account's Monthly Active Users.
138
- */
139
- userId: string;
140
- /**
141
- * The info associated to the user. Can be used to store the name or the profile picture to implement avatar for example. Can't exceed 1KB when serialized as JSON
142
- */
143
- userInfo?: unknown;
144
- /**
145
- * The ids of the groups to which the user belongs. It should be used to generate a token that gives access to a private room and at least one of the group is configured in the room accesses.
146
- */
147
- groupIds?: string[];
148
- };
149
- declare type AuthorizeResponse = {
150
- status: number;
151
- body: string;
152
- error?: Error;
153
- };
154
- /**
155
- * @example
156
- * export default async function auth(req, res) {
157
- *
158
- * // Implement your own security here.
159
- *
160
- * const room = req.body.room;
161
- * const response = await authorize({
162
- * room,
163
- * secret,
164
- * userId: "123",
165
- * userInfo: { // Optional
166
- * name: "Ada Lovelace"
167
- * },
168
- * groupIds: ["group1"] // Optional
169
- * });
170
- * return res.status(response.status).end(response.body);
171
- * }
172
- */
173
- declare function authorize(options: AuthorizeOptions): Promise<AuthorizeResponse>;
174
-
175
175
  export { StorageUpdatedEvent, UserEnteredEvent, UserLeftEvent, WebhookEvent, WebhookHandler, WebhookRequest, authorize };
package/dist/index.js CHANGED
@@ -19,8 +19,64 @@
19
19
  });
20
20
  };
21
21
 
22
- // src/index.ts
22
+ // src/authorize.ts
23
23
  var _nodefetch = require('node-fetch'); var _nodefetch2 = _interopRequireDefault(_nodefetch);
24
+ function authorize(options) {
25
+ return __async(this, null, function* () {
26
+ try {
27
+ const { room, secret, userId, userInfo, groupIds } = options;
28
+ if (!(typeof room === "string" && room.length > 0)) {
29
+ throw new Error(
30
+ "Invalid room. Please provide a non-empty string as the room. For more information: https://liveblocks.io/docs/api-reference/liveblocks-node#authorize"
31
+ );
32
+ }
33
+ if (!(typeof userId === "string" && userId.length > 0)) {
34
+ throw new Error(
35
+ "Invalid userId. Please provide a non-empty string as the userId. For more information: https://liveblocks.io/docs/api-reference/liveblocks-node#authorize"
36
+ );
37
+ }
38
+ const result = yield _nodefetch2.default.call(void 0,
39
+ buildLiveblocksAuthorizeEndpoint(options, room),
40
+ {
41
+ method: "POST",
42
+ headers: {
43
+ Authorization: `Bearer ${secret}`,
44
+ "Content-Type": "application/json"
45
+ },
46
+ body: JSON.stringify({
47
+ userId,
48
+ userInfo,
49
+ groupIds
50
+ })
51
+ }
52
+ );
53
+ if (!result.ok) {
54
+ return {
55
+ status: 403,
56
+ body: yield result.text()
57
+ };
58
+ }
59
+ return {
60
+ status: 200,
61
+ body: yield result.text()
62
+ };
63
+ } catch (er) {
64
+ return {
65
+ status: 403,
66
+ body: 'Call to "https://api.liveblocks.io/v2/rooms/:roomId/authorize" failed. See "error" for more information.',
67
+ error: er
68
+ };
69
+ }
70
+ });
71
+ }
72
+ function buildLiveblocksAuthorizeEndpoint(options, roomId) {
73
+ if (options.liveblocksAuthorizeEndpoint) {
74
+ return options.liveblocksAuthorizeEndpoint.replace("{roomId}", roomId);
75
+ }
76
+ return `https://api.liveblocks.io/v2/rooms/${encodeURIComponent(
77
+ roomId
78
+ )}/authorize`;
79
+ }
24
80
 
25
81
  // src/webhooks.ts
26
82
  var _crypto = require('crypto'); var _crypto2 = _interopRequireDefault(_crypto);
@@ -35,6 +91,9 @@ var _WebhookHandler = class {
35
91
  const secretKey = secret.slice(_WebhookHandler.secretPrefix.length);
36
92
  this.secretBuffer = Buffer.from(secretKey, "base64");
37
93
  }
94
+ /**
95
+ * Verifies a webhook request and returns the event
96
+ */
38
97
  verifyRequest(request) {
39
98
  const { webhookId, timestamp, rawSignatures } = this.verifyHeaders(
40
99
  request.headers
@@ -53,6 +112,9 @@ var _WebhookHandler = class {
53
112
  this.verifyWebhookEventType(event);
54
113
  return event;
55
114
  }
115
+ /**
116
+ * Verifies the headers and returns the webhookId, timestamp and rawSignatures
117
+ */
56
118
  verifyHeaders(headers) {
57
119
  const sanitizedHeaders = {};
58
120
  Object.keys(headers).forEach((key) => {
@@ -69,9 +131,17 @@ var _WebhookHandler = class {
69
131
  throw new Error("Invalid webhook-signature header");
70
132
  return { webhookId, timestamp, rawSignatures };
71
133
  }
134
+ /**
135
+ * Signs the content with the secret
136
+ * @param content
137
+ * @returns `string`
138
+ */
72
139
  sign(content) {
73
140
  return _crypto2.default.createHmac("sha256", this.secretBuffer).update(content).digest("base64");
74
141
  }
142
+ /**
143
+ * Verifies that the timestamp is not too old or in the future
144
+ */
75
145
  verifyTimestamp(timestampHeader) {
76
146
  const now = Math.floor(Date.now() / 1e3);
77
147
  const timestamp = parseInt(timestampHeader, 10);
@@ -85,6 +155,10 @@ var _WebhookHandler = class {
85
155
  throw new Error("Timestamp in the future");
86
156
  }
87
157
  }
158
+ /**
159
+ * Ensures that the event is a known event type
160
+ * or throws and prompts the user to upgrade to a higher version of @liveblocks/node
161
+ */
88
162
  verifyWebhookEventType(event) {
89
163
  if (event && event.type && [
90
164
  "storageUpdated",
@@ -104,64 +178,6 @@ WebhookHandler.secretPrefix = "whsec_";
104
178
  var WEBHOOK_TOLERANCE_IN_SECONDS = 5 * 60;
105
179
  var isNotUndefined = (value) => value !== void 0;
106
180
 
107
- // src/index.ts
108
- function authorize(options) {
109
- return __async(this, null, function* () {
110
- try {
111
- const { room, secret, userId, userInfo, groupIds } = options;
112
- if (!(typeof room === "string" && room.length > 0)) {
113
- throw new Error(
114
- "Invalid room. Please provide a non-empty string as the room. For more information: https://liveblocks.io/docs/api-reference/liveblocks-node#authorize"
115
- );
116
- }
117
- if (!(typeof userId === "string" && userId.length > 0)) {
118
- throw new Error(
119
- "Invalid userId. Please provide a non-empty string as the userId. For more information: https://liveblocks.io/docs/api-reference/liveblocks-node#authorize"
120
- );
121
- }
122
- const result = yield _nodefetch2.default.call(void 0,
123
- buildLiveblocksAuthorizeEndpoint(options, room),
124
- {
125
- method: "POST",
126
- headers: {
127
- Authorization: `Bearer ${secret}`,
128
- "Content-Type": "application/json"
129
- },
130
- body: JSON.stringify({
131
- userId,
132
- userInfo,
133
- groupIds
134
- })
135
- }
136
- );
137
- if (!result.ok) {
138
- return {
139
- status: 403,
140
- body: yield result.text()
141
- };
142
- }
143
- return {
144
- status: 200,
145
- body: yield result.text()
146
- };
147
- } catch (er) {
148
- return {
149
- status: 403,
150
- body: 'Call to "https://api.liveblocks.io/v2/rooms/:roomId/authorize" failed. See "error" for more information.',
151
- error: er
152
- };
153
- }
154
- });
155
- }
156
- function buildLiveblocksAuthorizeEndpoint(options, roomId) {
157
- if (options.liveblocksAuthorizeEndpoint) {
158
- return options.liveblocksAuthorizeEndpoint.replace("{roomId}", roomId);
159
- }
160
- return `https://api.liveblocks.io/v2/rooms/${encodeURIComponent(
161
- roomId
162
- )}/authorize`;
163
- }
164
-
165
181
 
166
182
 
167
183
  exports.WebhookHandler = WebhookHandler; exports.authorize = authorize;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liveblocks/node",
3
- "version": "1.0.2",
3
+ "version": "1.0.6-test2",
4
4
  "description": "A server-side utility that lets you set up a Liveblocks authentication endpoint. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.",
5
5
  "license": "Apache-2.0",
6
6
  "main": "./dist/index.js",