@pryv/delegation 3.14.2 → 3.16.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/package.json +1 -1
- package/src/index.d.ts +2 -1
- package/src/index.js +14 -2
- package/test/delegation.test.js +9 -0
package/README.md
CHANGED
|
@@ -103,6 +103,8 @@ const created = await delegation.createAccount({
|
|
|
103
103
|
|
|
104
104
|
## Detach requires a genuine login on B
|
|
105
105
|
|
|
106
|
+
When the delegate accepted cross-account consents for the account, the owner may keep some of them: `detachDelegate('parent-b', { keepAccessIds: ['<grant id>'] })` (core 2.0.0-rc.31 or later; each id must be a consent grant given through this relationship, else `delegation-invalid-keep-list` and nothing changes). The others are withdrawn and their requesters told.
|
|
107
|
+
|
|
106
108
|
`detachDelegate` and `cancelInvite` remove a delegation relationship, so they require the account owner to be **genuinely logged in** to the controlled account — a delegate PAT or a control token is rejected. A delegated session therefore cannot walk away with, or tear down, the relationship on its own.
|
|
107
109
|
|
|
108
110
|
The rejection surfaces as a typed [`DelegationError`](#typed-errors) with `id === delegationErrorIds.GENUINE_LOGIN_REQUIRED`. Surface it distinctly in your UI:
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -137,7 +137,8 @@ declare module '@pryv/delegation' {
|
|
|
137
137
|
requestAttach(delegateUsername: string): Promise<DelegationRecord>;
|
|
138
138
|
cancelInvite(delegateUsername: string): Promise<void>;
|
|
139
139
|
listDelegates(): Promise<DelegateRecord[]>;
|
|
140
|
-
|
|
140
|
+
/** `opts.keepAccessIds`: consent grants the delegate gave that the owner keeps (core 2.0.0-rc.31+). */
|
|
141
|
+
detachDelegate(delegateUsername: string, opts?: { keepAccessIds?: string[] }): Promise<void>;
|
|
141
142
|
|
|
142
143
|
// A side (the delegate)
|
|
143
144
|
acceptAttach(controlledUsername: string): Promise<DelegationRecord>;
|
package/src/index.js
CHANGED
|
@@ -243,11 +243,23 @@ class Delegation {
|
|
|
243
243
|
* — surface it distinctly so the UI can explain the account owner must log
|
|
244
244
|
* in directly (not through a delegated session) to remove a delegate.
|
|
245
245
|
*
|
|
246
|
+
* The account owner may keep consent grants the delegate gave (core
|
|
247
|
+
* 2.0.0-rc.31 or later): `opts.keepAccessIds` lists them; every other
|
|
248
|
+
* consent grant of the relationship is withdrawn. Each id must be such a
|
|
249
|
+
* grant, else `delegation-invalid-keep-list` and nothing is changed. An
|
|
250
|
+
* older core ignores the list and withdraws them all.
|
|
251
|
+
*
|
|
246
252
|
* @param {string} delegateUsername the delegate to detach.
|
|
253
|
+
* @param {Object} [opts]
|
|
254
|
+
* @param {string[]} [opts.keepAccessIds] consent grants the owner keeps.
|
|
247
255
|
* @returns {Promise<void>}
|
|
248
256
|
*/
|
|
249
|
-
async detachDelegate (delegateUsername) {
|
|
250
|
-
|
|
257
|
+
async detachDelegate (delegateUsername, opts) {
|
|
258
|
+
const params = { username: delegateUsername };
|
|
259
|
+
if (opts != null && Array.isArray(opts.keepAccessIds) && opts.keepAccessIds.length > 0) {
|
|
260
|
+
params.keepAccessIds = opts.keepAccessIds.slice();
|
|
261
|
+
}
|
|
262
|
+
await this._apiOne('delegations.detachDelegate', params);
|
|
251
263
|
}
|
|
252
264
|
|
|
253
265
|
// ---- A side (the delegate) --------------------------------------------
|
package/test/delegation.test.js
CHANGED
|
@@ -168,6 +168,15 @@ describe('[DELM] @pryv/delegation method → endpoint mapping', function () {
|
|
|
168
168
|
expect(conn.calls[0].method).to.equal('delegations.detachDelegate');
|
|
169
169
|
expect(conn.calls[0].params).to.deep.equal({ username: 'bob' });
|
|
170
170
|
});
|
|
171
|
+
|
|
172
|
+
it('[LCI2] detachDelegate passes keepAccessIds through, and sends none for an empty list', async function () {
|
|
173
|
+
const conn = makeStubConnection({ handlers: { 'delegations.detachDelegate': function () { return {}; } } });
|
|
174
|
+
const d = Delegation.fromConnection(conn);
|
|
175
|
+
await d.detachDelegate('bob', { keepAccessIds: ['g1', 'g2'] });
|
|
176
|
+
expect(conn.calls[0].params).to.deep.equal({ username: 'bob', keepAccessIds: ['g1', 'g2'] });
|
|
177
|
+
await d.detachDelegate('bob', { keepAccessIds: [] });
|
|
178
|
+
expect(conn.calls[1].params).to.deep.equal({ username: 'bob' });
|
|
179
|
+
});
|
|
171
180
|
});
|
|
172
181
|
|
|
173
182
|
describe('[DELMA] A-side (delegate)', function () {
|