@knocklabs/node 0.6.2 → 0.6.3

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/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knocklabs/node",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "Library for interacting with the Knock API",
5
5
  "homepage": "https://github.com/knocklabs/knock-node",
6
6
  "author": "@knocklabs",
@@ -1,3 +1,4 @@
1
+ import { TokenGrant } from "./userTokens";
1
2
  export interface KnockOptions {
2
3
  host?: string;
3
4
  }
@@ -57,6 +58,11 @@ export interface SignUserTokenOptions {
57
58
  signingKey?: string;
58
59
  /** The expiration time of the token in seconds. Defaults to 1 hour. */
59
60
  expiresInSeconds?: number;
61
+ /**
62
+ * A list of token grants to pass along with this token. The grants here provide permissions to
63
+ * the requested entities for the user
64
+ */
65
+ grants?: TokenGrant[];
60
66
  }
61
67
  export interface MethodOptions {
62
68
  idempotencyKey?: string;
@@ -0,0 +1,26 @@
1
+ export declare enum Grants {
2
+ SlackChannelsRead = "slack_channels/read",
3
+ ChannelDataRead = "channel_data/read",
4
+ ChannelDataWrite = "channel_data/write"
5
+ }
6
+ export type TokenGrantOptions = Grants[];
7
+ export type TokenEntity = TenantTokenEntity | UserTokenEntity | ObjectTokenEntity;
8
+ export interface TenantTokenEntity {
9
+ type: "tenant";
10
+ id: string;
11
+ collection?: never;
12
+ }
13
+ export interface ObjectTokenEntity {
14
+ type: "object";
15
+ id: string;
16
+ collection: string;
17
+ }
18
+ export interface UserTokenEntity {
19
+ type: "user";
20
+ id: string;
21
+ collection?: never;
22
+ }
23
+ export type TokenGrant = {
24
+ entity: string;
25
+ grants: Partial<Record<Grants, []>>;
26
+ };
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Grants = void 0;
4
+ var Grants;
5
+ (function (Grants) {
6
+ Grants["SlackChannelsRead"] = "slack_channels/read";
7
+ Grants["ChannelDataRead"] = "channel_data/read";
8
+ Grants["ChannelDataWrite"] = "channel_data/write";
9
+ })(Grants || (exports.Grants = Grants = {}));
@@ -7,6 +7,7 @@ import { Objects } from "./resources/objects";
7
7
  import { Messages } from "./resources/messages";
8
8
  import { Tenants } from "./resources/tenants";
9
9
  import { FetchResponse } from "./common/fetchClient";
10
+ import { TokenEntity, TokenGrant, TokenGrantOptions } from "./common/userTokens";
10
11
  declare class Knock {
11
12
  readonly key?: string | undefined;
12
13
  readonly options: KnockOptions;
@@ -29,6 +30,15 @@ declare class Knock {
29
30
  * @returns {Promise<string>} A JWT token that can be used to authenticate requests to the Knock API (e.g. by passing into the <KnockFeedProvider /> component)
30
31
  */
31
32
  static signUserToken(userId: string, options?: SignUserTokenOptions): Promise<string>;
33
+ /**
34
+ * Helper function to build user token grants to pass to the `signUserToken` method.
35
+ *
36
+ * @param entity {TokenEntity} The type of entity to build a grant for
37
+ * @param grants {TokenGrantOptions} A list of grants to give to the entity for the user
38
+ *
39
+ * @returns {TokenGrant} A single token grant that can be passed to the signUserToken function
40
+ */
41
+ static buildUserTokenGrant(entity: TokenEntity, grants: TokenGrantOptions): TokenGrant;
32
42
  post(path: string, entity: any, options?: PostAndPutOptions): Promise<FetchResponse>;
33
43
  put(path: string, entity: any, options?: PostAndPutOptions): Promise<FetchResponse>;
34
44
  delete(path: string, entity?: any): Promise<FetchResponse>;
@@ -36,4 +46,5 @@ declare class Knock {
36
46
  handleErrorResponse(path: string, error: any): void;
37
47
  emitWarning(warning: string): void;
38
48
  }
49
+ export declare function maybePrepareUserTokenGrants(grants: TokenGrant[] | undefined): Record<string, TokenGrant["grants"]> | undefined;
39
50
  export { Knock };
package/dist/src/knock.js CHANGED
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.Knock = void 0;
15
+ exports.Knock = exports.maybePrepareUserTokenGrants = void 0;
16
16
  const jose_1 = require("jose");
17
17
  const package_json_1 = require("../package.json");
18
18
  const exceptions_1 = require("./common/exceptions");
@@ -78,6 +78,7 @@ class Knock {
78
78
  const keyLike = yield (0, jose_1.importPKCS8)(signingKey, "RS256");
79
79
  return yield new jose_1.SignJWT({
80
80
  sub: userId,
81
+ grants: maybePrepareUserTokenGrants(options === null || options === void 0 ? void 0 : options.grants),
81
82
  iat: currentTime,
82
83
  exp: currentTime + expireInSeconds,
83
84
  })
@@ -85,6 +86,20 @@ class Knock {
85
86
  .sign(keyLike);
86
87
  });
87
88
  }
89
+ /**
90
+ * Helper function to build user token grants to pass to the `signUserToken` method.
91
+ *
92
+ * @param entity {TokenEntity} The type of entity to build a grant for
93
+ * @param grants {TokenGrantOptions} A list of grants to give to the entity for the user
94
+ *
95
+ * @returns {TokenGrant} A single token grant that can be passed to the signUserToken function
96
+ */
97
+ static buildUserTokenGrant(entity, grants) {
98
+ return {
99
+ entity: prepareTokenEntityUri(entity),
100
+ grants: grants.reduce((acc, grant) => (Object.assign(Object.assign({}, acc), { [grant]: [] })), {}),
101
+ };
102
+ }
88
103
  post(path, entity, options = {}) {
89
104
  return __awaiter(this, void 0, void 0, function* () {
90
105
  try {
@@ -192,3 +207,29 @@ function prepareSigningKey(key) {
192
207
  return Buffer.from(maybeSigningKey, "base64").toString("utf-8");
193
208
  throw new exceptions_1.NoSigningKeyProvidedException();
194
209
  }
210
+ function prepareTokenEntityUri(entity) {
211
+ switch (entity.type) {
212
+ case "user":
213
+ return `${DEFAULT_HOSTNAME}/v1/users/${entity.id}`;
214
+ case "tenant":
215
+ return `${DEFAULT_HOSTNAME}/v1/objects/$tenants/${entity.id}`;
216
+ case "object":
217
+ return `${DEFAULT_HOSTNAME}/v1/objects/${entity.collection}/${entity.id}`;
218
+ }
219
+ }
220
+ function maybePrepareUserTokenGrants(grants) {
221
+ if (!grants)
222
+ return undefined;
223
+ // Given a list of token grants, flattens them into a single object
224
+ // like: { "entity": { "slack_channels/read": [] } }
225
+ return grants.reduce((acc, grant) => {
226
+ if (acc[grant.entity]) {
227
+ const currentGrants = acc[grant.entity];
228
+ return Object.assign(Object.assign({}, acc), { [grant.entity]: Object.assign(Object.assign({}, currentGrants), grant.grants) });
229
+ }
230
+ else {
231
+ return Object.assign(Object.assign({}, acc), { [grant.entity]: grant.grants });
232
+ }
233
+ }, {});
234
+ }
235
+ exports.maybePrepareUserTokenGrants = maybePrepareUserTokenGrants;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knocklabs/node",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "Library for interacting with the Knock API",
5
5
  "homepage": "https://github.com/knocklabs/knock-node",
6
6
  "author": "@knocklabs",
@@ -42,4 +42,4 @@
42
42
  "dependencies": {
43
43
  "jose": "^5.2.0"
44
44
  }
45
- }
45
+ }