toolpass-client 0.12.0 → 0.13.0
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 +2 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +17 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,6 +50,8 @@ const d = await tp.check("dana@example.com", "jira-main", "DELETE_ISSUES", "issu
|
|
|
50
50
|
d.decision, d.reason; // "deny", "denied: ..."
|
|
51
51
|
d.identity; // the account the email resolved to (a GitHub login), "" if none
|
|
52
52
|
await tp.require(...); // rejects with PermissionDenied unless allow
|
|
53
|
+
// The fifth argument: the user's groups, or { groups, fresh, token } (token: the user's own
|
|
54
|
+
// ID token, for a connection that reads the groups from it: oidc_issuer).
|
|
53
55
|
```
|
|
54
56
|
|
|
55
57
|
Framework examples: [examples/agent-ts](https://github.com/roee-hersh/toolpass/tree/main/examples/agent-ts).
|
package/dist/index.d.ts
CHANGED
|
@@ -91,8 +91,10 @@ export declare class Toolpass {
|
|
|
91
91
|
/**
|
|
92
92
|
* Ask toolpass. Never rejects on transport: every failure becomes an
|
|
93
93
|
* `unknown` decision. The fifth argument is the user's groups, or an
|
|
94
|
-
* options object: `{ groups, fresh }`. Groups left out or null are
|
|
95
|
-
* omitted from the request.
|
|
94
|
+
* options object: `{ groups, fresh, token }`. Groups left out or null are
|
|
95
|
+
* omitted from the request. `token` is the user's own login token (an
|
|
96
|
+
* OIDC ID token), for a connection that reads the groups from it
|
|
97
|
+
* (`oidc_issuer`).
|
|
96
98
|
*
|
|
97
99
|
* `fresh: true` asks for an answer straight from the upstream system,
|
|
98
100
|
* skipping toolpass's caches. Use it for destructive actions. It narrows
|
|
@@ -109,6 +111,8 @@ export declare class Toolpass {
|
|
|
109
111
|
export interface CheckOptions {
|
|
110
112
|
/** The user's groups; left out or null, none are sent. */
|
|
111
113
|
groups?: readonly string[] | null;
|
|
114
|
+
/** The user's own login token (an OIDC ID token); left out or null, none is sent. */
|
|
115
|
+
token?: string | null;
|
|
112
116
|
/** Skip toolpass's caches and ask the upstream system now. */
|
|
113
117
|
fresh?: boolean;
|
|
114
118
|
}
|
package/dist/index.js
CHANGED
|
@@ -108,8 +108,10 @@ export class Toolpass {
|
|
|
108
108
|
/**
|
|
109
109
|
* Ask toolpass. Never rejects on transport: every failure becomes an
|
|
110
110
|
* `unknown` decision. The fifth argument is the user's groups, or an
|
|
111
|
-
* options object: `{ groups, fresh }`. Groups left out or null are
|
|
112
|
-
* omitted from the request.
|
|
111
|
+
* options object: `{ groups, fresh, token }`. Groups left out or null are
|
|
112
|
+
* omitted from the request. `token` is the user's own login token (an
|
|
113
|
+
* OIDC ID token), for a connection that reads the groups from it
|
|
114
|
+
* (`oidc_issuer`).
|
|
113
115
|
*
|
|
114
116
|
* `fresh: true` asks for an answer straight from the upstream system,
|
|
115
117
|
* skipping toolpass's caches. Use it for destructive actions. It narrows
|
|
@@ -117,7 +119,7 @@ export class Toolpass {
|
|
|
117
119
|
* two; it does not close it.
|
|
118
120
|
*/
|
|
119
121
|
async check(user, connection, action, resource, options) {
|
|
120
|
-
const { groups, fresh } = checkOptions(options);
|
|
122
|
+
const { groups, fresh, token } = checkOptions(options);
|
|
121
123
|
const body = { user, connection, action, resource };
|
|
122
124
|
if (groups != null) {
|
|
123
125
|
body.groups = groupList(groups);
|
|
@@ -125,6 +127,9 @@ export class Toolpass {
|
|
|
125
127
|
if (fresh) {
|
|
126
128
|
body.fresh = true;
|
|
127
129
|
}
|
|
130
|
+
if (token) {
|
|
131
|
+
body.token = token;
|
|
132
|
+
}
|
|
128
133
|
let response;
|
|
129
134
|
let raw;
|
|
130
135
|
try {
|
|
@@ -206,28 +211,31 @@ function isLoopback(hostname) {
|
|
|
206
211
|
}
|
|
207
212
|
function checkOptions(o) {
|
|
208
213
|
if (o == null) {
|
|
209
|
-
return { groups: null, fresh: false };
|
|
214
|
+
return { groups: null, fresh: false, token: "" };
|
|
210
215
|
}
|
|
211
216
|
if (Array.isArray(o)) {
|
|
212
|
-
return { groups: o, fresh: false };
|
|
217
|
+
return { groups: o, fresh: false, token: "" };
|
|
213
218
|
}
|
|
214
219
|
if (typeof o === "boolean") {
|
|
215
|
-
throw new TypeError("the fifth argument is the groups array or { groups, fresh }; pass { fresh: true } for a fresh check");
|
|
220
|
+
throw new TypeError("the fifth argument is the groups array or { groups, fresh, token }; pass { fresh: true } for a fresh check");
|
|
216
221
|
}
|
|
217
222
|
if (typeof o !== "object" || Symbol.iterator in o) {
|
|
218
223
|
// A Set or another iterable of groups is not an array of them.
|
|
219
224
|
throw new TypeError("groups must be an array of strings");
|
|
220
225
|
}
|
|
221
226
|
for (const key of Object.keys(o)) {
|
|
222
|
-
if (key !== "groups" && key !== "fresh") {
|
|
223
|
-
throw new TypeError(`unknown check option ${JSON.stringify(key)}; the options are groups and
|
|
227
|
+
if (key !== "groups" && key !== "fresh" && key !== "token") {
|
|
228
|
+
throw new TypeError(`unknown check option ${JSON.stringify(key)}; the options are groups, fresh and token`);
|
|
224
229
|
}
|
|
225
230
|
}
|
|
226
231
|
const opts = o;
|
|
227
232
|
if (opts.fresh !== undefined && typeof opts.fresh !== "boolean") {
|
|
228
233
|
throw new TypeError("fresh must be a boolean");
|
|
229
234
|
}
|
|
230
|
-
|
|
235
|
+
if (opts.token != null && typeof opts.token !== "string") {
|
|
236
|
+
throw new TypeError("token must be a string");
|
|
237
|
+
}
|
|
238
|
+
return { groups: opts.groups ?? null, fresh: opts.fresh === true, token: opts.token ?? "" };
|
|
231
239
|
}
|
|
232
240
|
function groupList(groups) {
|
|
233
241
|
if (typeof groups === "string" || !Array.isArray(groups) || !groups.every((g) => typeof g === "string")) {
|