@kubun/service-credential-api 0.17.3 → 0.18.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/lib/adapter.d.ts +2 -2
- package/lib/adapter.js +60 -2
- package/lib/errors.d.ts +7 -0
- package/lib/errors.js +12 -0
- package/lib/index.d.ts +49 -2
- package/lib/index.js +57 -2
- package/package.json +5 -5
package/lib/adapter.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Client } from '@enkaku/client';
|
|
2
|
-
import type { AliasBindingCredentialProvider, CredentialProvider, EntryPairedCredentialProvider, ProviderAccount } from '@kubun/credential-types';
|
|
2
|
+
import type { AdoptGrantAPI, AliasBindingCredentialProvider, CredentialProvider, EntryPairedCredentialProvider, ProviderAccount, VersionedEntryCredentialProvider } from '@kubun/credential-types';
|
|
3
3
|
import type { CredentialServiceProtocol } from './index.js';
|
|
4
4
|
/**
|
|
5
5
|
* What a storage-only account peek discloses: the provider account and the
|
|
@@ -22,4 +22,4 @@ export type CredentialProviderWithProvenance = CredentialProvider & {
|
|
|
22
22
|
writerDID: string | null;
|
|
23
23
|
} | null>;
|
|
24
24
|
};
|
|
25
|
-
export declare function toCredentialProvider(client: Client<CredentialServiceProtocol>): CredentialProviderWithProvenance & AliasBindingCredentialProvider & EntryPairedCredentialProvider & Required<Pick<CredentialProviderWithProvenance, 'peekAccount'>>;
|
|
25
|
+
export declare function toCredentialProvider(client: Client<CredentialServiceProtocol>): CredentialProviderWithProvenance & AliasBindingCredentialProvider & EntryPairedCredentialProvider & VersionedEntryCredentialProvider & AdoptGrantAPI & Required<Pick<CredentialProviderWithProvenance, 'peekAccount'>>;
|
package/lib/adapter.js
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
import { RequestError } from '@enkaku/client';
|
|
7
7
|
import { ErrorCodes } from '@enkaku/protocol';
|
|
8
8
|
import { deserializeCredential, serializeCredential } from '@kubun/credential';
|
|
9
|
-
import {
|
|
9
|
+
import { CredentialUpdateUnavailableError } from '@kubun/credential-types';
|
|
10
|
+
import { CredentialPeekUnsupportedError, CredentialUnexpectedSupersededError } from './errors.js';
|
|
10
11
|
export function toCredentialProvider(client) {
|
|
11
12
|
return {
|
|
12
13
|
async get (providerName, ownerDID) {
|
|
@@ -30,8 +31,58 @@ export function toCredentialProvider(client) {
|
|
|
30
31
|
entryID: ref.entryID
|
|
31
32
|
};
|
|
32
33
|
},
|
|
33
|
-
|
|
34
|
+
async getVersionedCredentialRef (providerName, ownerDID) {
|
|
35
|
+
const ref = await client.request('credential/get-ref', {
|
|
36
|
+
param: {
|
|
37
|
+
providerName,
|
|
38
|
+
ownerDID
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
return ref == null ? null : {
|
|
42
|
+
credential: deserializeCredential(ref.credential),
|
|
43
|
+
entryID: ref.entryID,
|
|
44
|
+
...ref.version == null ? {} : {
|
|
45
|
+
version: ref.version
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
setCredentialForEntryIfUnchanged ({ providerName, ownerDID, entryID, credential, expectedVersion }) {
|
|
34
50
|
return client.request('credential/refresh-entry', {
|
|
51
|
+
param: {
|
|
52
|
+
providerName,
|
|
53
|
+
ownerDID,
|
|
54
|
+
entryID,
|
|
55
|
+
credential: serializeCredential(credential),
|
|
56
|
+
expectedVersion
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
async update (address, change) {
|
|
61
|
+
for(;;){
|
|
62
|
+
const ref = await client.request('credential/get-ref', {
|
|
63
|
+
param: {
|
|
64
|
+
providerName: address.providerName,
|
|
65
|
+
ownerDID: address.ownerDID,
|
|
66
|
+
deviceDID: address.deviceDID
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
if (ref == null || ref.version == null) throw new CredentialUpdateUnavailableError();
|
|
70
|
+
const result = await client.request('credential/refresh-entry', {
|
|
71
|
+
param: {
|
|
72
|
+
providerName: address.providerName,
|
|
73
|
+
ownerDID: address.ownerDID,
|
|
74
|
+
deviceDID: address.deviceDID,
|
|
75
|
+
entryID: ref.entryID,
|
|
76
|
+
credential: serializeCredential(change(deserializeCredential(ref.credential))),
|
|
77
|
+
expectedVersion: ref.version
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
if (result === 'updated') return;
|
|
81
|
+
if (result === 'absent') throw new CredentialUpdateUnavailableError();
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
async setCredentialForEntry ({ providerName, ownerDID, entryID, credential }) {
|
|
85
|
+
const result = await client.request('credential/refresh-entry', {
|
|
35
86
|
param: {
|
|
36
87
|
providerName,
|
|
37
88
|
ownerDID,
|
|
@@ -39,6 +90,8 @@ export function toCredentialProvider(client) {
|
|
|
39
90
|
credential: serializeCredential(credential)
|
|
40
91
|
}
|
|
41
92
|
});
|
|
93
|
+
if (result === 'superseded') throw new CredentialUnexpectedSupersededError();
|
|
94
|
+
return result;
|
|
42
95
|
},
|
|
43
96
|
async peekAccount (providerName, ownerDID) {
|
|
44
97
|
let peeked;
|
|
@@ -119,6 +172,11 @@ export function toCredentialProvider(client) {
|
|
|
119
172
|
entryID
|
|
120
173
|
}
|
|
121
174
|
});
|
|
175
|
+
},
|
|
176
|
+
async adoptCredentialGrant (params) {
|
|
177
|
+
await client.request('credential/adopt-grant', {
|
|
178
|
+
param: params
|
|
179
|
+
});
|
|
122
180
|
}
|
|
123
181
|
};
|
|
124
182
|
}
|
package/lib/errors.d.ts
CHANGED
|
@@ -16,3 +16,10 @@ export declare class CredentialPeekUnsupportedError extends Error {
|
|
|
16
16
|
constructor(options?: ErrorOptions);
|
|
17
17
|
get code(): typeof CREDENTIAL_PEEK_UNSUPPORTED;
|
|
18
18
|
}
|
|
19
|
+
/** An unconditional entry write received a result reserved for versioned writes. */
|
|
20
|
+
export declare const CREDENTIAL_UNEXPECTED_SUPERSEDED = "CREDENTIAL_UNEXPECTED_SUPERSEDED";
|
|
21
|
+
export declare class CredentialUnexpectedSupersededError extends Error {
|
|
22
|
+
#private;
|
|
23
|
+
constructor();
|
|
24
|
+
get code(): typeof CREDENTIAL_UNEXPECTED_SUPERSEDED;
|
|
25
|
+
}
|
package/lib/errors.js
CHANGED
|
@@ -20,3 +20,15 @@
|
|
|
20
20
|
return this.#code;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
+
/** An unconditional entry write received a result reserved for versioned writes. */ export const CREDENTIAL_UNEXPECTED_SUPERSEDED = 'CREDENTIAL_UNEXPECTED_SUPERSEDED';
|
|
24
|
+
export class CredentialUnexpectedSupersededError extends Error {
|
|
25
|
+
#code;
|
|
26
|
+
constructor(){
|
|
27
|
+
super('The credential service superseded an unconditional entry write');
|
|
28
|
+
this.name = 'CredentialUnexpectedSupersededError';
|
|
29
|
+
this.#code = CREDENTIAL_UNEXPECTED_SUPERSEDED;
|
|
30
|
+
}
|
|
31
|
+
get code() {
|
|
32
|
+
return this.#code;
|
|
33
|
+
}
|
|
34
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { type CredentialAccountPeek, type CredentialProviderWithProvenance, toCredentialProvider, } from './adapter.js';
|
|
2
|
-
export { CREDENTIAL_PEEK_UNSUPPORTED, CredentialPeekUnsupportedError } from './errors.js';
|
|
2
|
+
export { CREDENTIAL_PEEK_UNSUPPORTED, CREDENTIAL_UNEXPECTED_SUPERSEDED, CredentialPeekUnsupportedError, CredentialUnexpectedSupersededError, } from './errors.js';
|
|
3
3
|
export declare const credentialServiceProtocol: {
|
|
4
4
|
readonly 'credential/get': {
|
|
5
5
|
readonly type: "request";
|
|
@@ -35,6 +35,9 @@ export declare const credentialServiceProtocol: {
|
|
|
35
35
|
readonly ownerDID: {
|
|
36
36
|
readonly type: "string";
|
|
37
37
|
};
|
|
38
|
+
readonly deviceDID: {
|
|
39
|
+
readonly type: "string";
|
|
40
|
+
};
|
|
38
41
|
};
|
|
39
42
|
readonly required: readonly ["providerName", "ownerDID"];
|
|
40
43
|
readonly additionalProperties: false;
|
|
@@ -49,6 +52,9 @@ export declare const credentialServiceProtocol: {
|
|
|
49
52
|
readonly entryID: {
|
|
50
53
|
readonly type: "string";
|
|
51
54
|
};
|
|
55
|
+
readonly version: {
|
|
56
|
+
readonly type: "string";
|
|
57
|
+
};
|
|
52
58
|
};
|
|
53
59
|
readonly required: readonly ["credential", "entryID"];
|
|
54
60
|
readonly additionalProperties: false;
|
|
@@ -209,19 +215,60 @@ export declare const credentialServiceProtocol: {
|
|
|
209
215
|
readonly ownerDID: {
|
|
210
216
|
readonly type: "string";
|
|
211
217
|
};
|
|
218
|
+
readonly deviceDID: {
|
|
219
|
+
readonly type: "string";
|
|
220
|
+
};
|
|
212
221
|
readonly entryID: {
|
|
213
222
|
readonly type: "string";
|
|
214
223
|
};
|
|
215
224
|
readonly credential: {
|
|
216
225
|
readonly type: "string";
|
|
217
226
|
};
|
|
227
|
+
readonly expectedVersion: {
|
|
228
|
+
readonly type: "string";
|
|
229
|
+
};
|
|
218
230
|
};
|
|
219
231
|
readonly required: readonly ["providerName", "ownerDID", "entryID", "credential"];
|
|
220
232
|
readonly additionalProperties: false;
|
|
221
233
|
};
|
|
222
234
|
readonly result: {
|
|
223
235
|
readonly type: "string";
|
|
224
|
-
readonly enum: readonly ["updated", "absent"];
|
|
236
|
+
readonly enum: readonly ["updated", "absent", "superseded"];
|
|
237
|
+
};
|
|
238
|
+
};
|
|
239
|
+
readonly 'credential/adopt-grant': {
|
|
240
|
+
readonly type: "request";
|
|
241
|
+
readonly param: {
|
|
242
|
+
readonly type: "object";
|
|
243
|
+
readonly properties: {
|
|
244
|
+
readonly providerName: {
|
|
245
|
+
readonly type: "string";
|
|
246
|
+
};
|
|
247
|
+
readonly ownerDID: {
|
|
248
|
+
readonly type: "string";
|
|
249
|
+
};
|
|
250
|
+
readonly fromDeviceDID: {
|
|
251
|
+
readonly type: "string";
|
|
252
|
+
};
|
|
253
|
+
readonly toDeviceDID: {
|
|
254
|
+
readonly type: "string";
|
|
255
|
+
};
|
|
256
|
+
readonly sourceKeyOwnerDID: {
|
|
257
|
+
readonly type: "string";
|
|
258
|
+
};
|
|
259
|
+
};
|
|
260
|
+
readonly required: readonly ["providerName", "ownerDID", "fromDeviceDID", "toDeviceDID"];
|
|
261
|
+
readonly additionalProperties: false;
|
|
262
|
+
};
|
|
263
|
+
readonly result: {
|
|
264
|
+
readonly type: "object";
|
|
265
|
+
readonly properties: {
|
|
266
|
+
readonly adopted: {
|
|
267
|
+
readonly type: "boolean";
|
|
268
|
+
};
|
|
269
|
+
};
|
|
270
|
+
readonly required: readonly ["adopted"];
|
|
271
|
+
readonly additionalProperties: false;
|
|
225
272
|
};
|
|
226
273
|
};
|
|
227
274
|
readonly 'credential/delete': {
|
package/lib/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// authenticated client into the `credential-provider` the connector registers, so
|
|
6
6
|
// this package is no longer type-only.
|
|
7
7
|
export { toCredentialProvider } from './adapter.js';
|
|
8
|
-
export { CREDENTIAL_PEEK_UNSUPPORTED, CredentialPeekUnsupportedError } from './errors.js';
|
|
8
|
+
export { CREDENTIAL_PEEK_UNSUPPORTED, CREDENTIAL_UNEXPECTED_SUPERSEDED, CredentialPeekUnsupportedError, CredentialUnexpectedSupersededError } from './errors.js';
|
|
9
9
|
// Param↔seam mapping. `providerName`/`ownerDID` are the alias key the seam
|
|
10
10
|
// resolves. `ownerDID` is ALSO the authorization subject: each handler passes it
|
|
11
11
|
// to `context.authorize(ownerDID)` (the per-serve `callerMayActFor`), NOT the
|
|
@@ -54,6 +54,9 @@ export const credentialServiceProtocol = {
|
|
|
54
54
|
},
|
|
55
55
|
ownerDID: {
|
|
56
56
|
type: 'string'
|
|
57
|
+
},
|
|
58
|
+
deviceDID: {
|
|
59
|
+
type: 'string'
|
|
57
60
|
}
|
|
58
61
|
},
|
|
59
62
|
required: [
|
|
@@ -72,6 +75,9 @@ export const credentialServiceProtocol = {
|
|
|
72
75
|
},
|
|
73
76
|
entryID: {
|
|
74
77
|
type: 'string'
|
|
78
|
+
},
|
|
79
|
+
version: {
|
|
80
|
+
type: 'string'
|
|
75
81
|
}
|
|
76
82
|
},
|
|
77
83
|
required: [
|
|
@@ -288,11 +294,17 @@ export const credentialServiceProtocol = {
|
|
|
288
294
|
ownerDID: {
|
|
289
295
|
type: 'string'
|
|
290
296
|
},
|
|
297
|
+
deviceDID: {
|
|
298
|
+
type: 'string'
|
|
299
|
+
},
|
|
291
300
|
entryID: {
|
|
292
301
|
type: 'string'
|
|
293
302
|
},
|
|
294
303
|
credential: {
|
|
295
304
|
type: 'string'
|
|
305
|
+
},
|
|
306
|
+
expectedVersion: {
|
|
307
|
+
type: 'string'
|
|
296
308
|
}
|
|
297
309
|
},
|
|
298
310
|
required: [
|
|
@@ -307,10 +319,53 @@ export const credentialServiceProtocol = {
|
|
|
307
319
|
type: 'string',
|
|
308
320
|
enum: [
|
|
309
321
|
'updated',
|
|
310
|
-
'absent'
|
|
322
|
+
'absent',
|
|
323
|
+
'superseded'
|
|
311
324
|
]
|
|
312
325
|
}
|
|
313
326
|
},
|
|
327
|
+
'credential/adopt-grant': {
|
|
328
|
+
type: 'request',
|
|
329
|
+
param: {
|
|
330
|
+
type: 'object',
|
|
331
|
+
properties: {
|
|
332
|
+
providerName: {
|
|
333
|
+
type: 'string'
|
|
334
|
+
},
|
|
335
|
+
ownerDID: {
|
|
336
|
+
type: 'string'
|
|
337
|
+
},
|
|
338
|
+
fromDeviceDID: {
|
|
339
|
+
type: 'string'
|
|
340
|
+
},
|
|
341
|
+
toDeviceDID: {
|
|
342
|
+
type: 'string'
|
|
343
|
+
},
|
|
344
|
+
sourceKeyOwnerDID: {
|
|
345
|
+
type: 'string'
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
required: [
|
|
349
|
+
'providerName',
|
|
350
|
+
'ownerDID',
|
|
351
|
+
'fromDeviceDID',
|
|
352
|
+
'toDeviceDID'
|
|
353
|
+
],
|
|
354
|
+
additionalProperties: false
|
|
355
|
+
},
|
|
356
|
+
result: {
|
|
357
|
+
type: 'object',
|
|
358
|
+
properties: {
|
|
359
|
+
adopted: {
|
|
360
|
+
type: 'boolean'
|
|
361
|
+
}
|
|
362
|
+
},
|
|
363
|
+
required: [
|
|
364
|
+
'adopted'
|
|
365
|
+
],
|
|
366
|
+
additionalProperties: false
|
|
367
|
+
}
|
|
368
|
+
},
|
|
314
369
|
'credential/delete': {
|
|
315
370
|
type: 'request',
|
|
316
371
|
param: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubun/service-credential-api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"keywords": [],
|
|
5
5
|
"license": "see LICENSE.md",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
"LICENSE.md"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@enkaku/client": "^0.21.
|
|
19
|
-
"@enkaku/protocol": "^0.21.
|
|
20
|
-
"@kubun/credential": "^0.
|
|
21
|
-
"@kubun/credential-types": "^0.
|
|
18
|
+
"@enkaku/client": "^0.21.5",
|
|
19
|
+
"@enkaku/protocol": "^0.21.5",
|
|
20
|
+
"@kubun/credential": "^0.18.0",
|
|
21
|
+
"@kubun/credential-types": "^0.18.0"
|
|
22
22
|
},
|
|
23
23
|
"publishConfig": {
|
|
24
24
|
"access": "public"
|