@auths-dev/sdk 0.0.1 → 0.1.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/Cargo.toml +45 -0
- package/README.md +163 -4
- package/__test__/client.spec.ts +78 -0
- package/__test__/exports.spec.ts +57 -0
- package/__test__/integration.spec.ts +407 -0
- package/__test__/policy.spec.ts +202 -0
- package/__test__/verify.spec.ts +88 -0
- package/build.rs +5 -0
- package/index.d.ts +259 -0
- package/index.js +622 -1
- package/lib/artifacts.ts +124 -0
- package/lib/attestations.ts +126 -0
- package/lib/audit.ts +189 -0
- package/lib/client.ts +293 -0
- package/lib/commits.ts +70 -0
- package/lib/devices.ts +178 -0
- package/lib/errors.ts +306 -0
- package/lib/identity.ts +280 -0
- package/lib/index.ts +125 -0
- package/lib/native.ts +255 -0
- package/lib/org.ts +235 -0
- package/lib/pairing.ts +271 -0
- package/lib/policy.ts +669 -0
- package/lib/signing.ts +204 -0
- package/lib/trust.ts +152 -0
- package/lib/types.ts +179 -0
- package/lib/verify.ts +241 -0
- package/lib/witness.ts +91 -0
- package/npm/darwin-arm64/README.md +3 -0
- package/npm/darwin-arm64/package.json +23 -0
- package/npm/linux-arm64-gnu/README.md +3 -0
- package/npm/linux-arm64-gnu/package.json +26 -0
- package/npm/linux-x64-gnu/README.md +3 -0
- package/npm/linux-x64-gnu/package.json +26 -0
- package/npm/win32-arm64-msvc/README.md +3 -0
- package/npm/win32-arm64-msvc/package.json +23 -0
- package/npm/win32-x64-msvc/README.md +3 -0
- package/npm/win32-x64-msvc/package.json +23 -0
- package/package.json +51 -16
- package/src/artifact.rs +217 -0
- package/src/attestation_query.rs +104 -0
- package/src/audit.rs +128 -0
- package/src/commit_sign.rs +63 -0
- package/src/device.rs +212 -0
- package/src/diagnostics.rs +106 -0
- package/src/error.rs +5 -0
- package/src/helpers.rs +60 -0
- package/src/identity.rs +467 -0
- package/src/lib.rs +26 -0
- package/src/org.rs +430 -0
- package/src/pairing.rs +454 -0
- package/src/policy.rs +147 -0
- package/src/sign.rs +215 -0
- package/src/trust.rs +189 -0
- package/src/types.rs +205 -0
- package/src/verify.rs +447 -0
- package/src/witness.rs +138 -0
- package/tsconfig.json +19 -0
- package/typedoc.json +18 -0
- package/vitest.config.ts +12 -0
package/lib/client.ts
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { IdentityService, type GetPublicKeyOptions } from './identity'
|
|
2
|
+
import { DeviceService } from './devices'
|
|
3
|
+
import {
|
|
4
|
+
SigningService,
|
|
5
|
+
type SignResult,
|
|
6
|
+
type ActionEnvelope,
|
|
7
|
+
type SignAsIdentityOptions,
|
|
8
|
+
type SignActionAsIdentityOptions,
|
|
9
|
+
type SignAsAgentOptions,
|
|
10
|
+
type SignActionAsAgentOptions,
|
|
11
|
+
} from './signing'
|
|
12
|
+
import { OrgService } from './org'
|
|
13
|
+
import { TrustService } from './trust'
|
|
14
|
+
import { WitnessService } from './witness'
|
|
15
|
+
import { AttestationService } from './attestations'
|
|
16
|
+
import { ArtifactService } from './artifacts'
|
|
17
|
+
import { CommitService } from './commits'
|
|
18
|
+
import { AuditService } from './audit'
|
|
19
|
+
import { PairingService } from './pairing'
|
|
20
|
+
import { mapNativeError, CryptoError, VerificationError } from './errors'
|
|
21
|
+
import {
|
|
22
|
+
verifyAttestation,
|
|
23
|
+
verifyAttestationWithCapability,
|
|
24
|
+
verifyAtTime,
|
|
25
|
+
verifyAtTimeWithCapability,
|
|
26
|
+
verifyChain as verifyChainFn,
|
|
27
|
+
verifyChainWithCapability,
|
|
28
|
+
verifyChainWithWitnesses,
|
|
29
|
+
type VerificationResult,
|
|
30
|
+
type VerificationReport,
|
|
31
|
+
type WitnessConfig,
|
|
32
|
+
} from './verify'
|
|
33
|
+
import native from './native'
|
|
34
|
+
|
|
35
|
+
/** Configuration for the {@link Auths} client. */
|
|
36
|
+
export interface ClientConfig {
|
|
37
|
+
/** Path to the Auths Git registry. Defaults to `'~/.auths'`. */
|
|
38
|
+
repoPath?: string
|
|
39
|
+
/** Passphrase for key encryption. Can also be set via `AUTHS_PASSPHRASE` env var. */
|
|
40
|
+
passphrase?: string
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Options for {@link Auths.verify}. */
|
|
44
|
+
export interface VerifyOptions {
|
|
45
|
+
/** JSON-serialized attestation to verify. */
|
|
46
|
+
attestationJson: string
|
|
47
|
+
/** Hex-encoded Ed25519 public key of the issuer. */
|
|
48
|
+
issuerKey: string
|
|
49
|
+
/** Optional capability the attestation must grant. */
|
|
50
|
+
requiredCapability?: string
|
|
51
|
+
/** Optional RFC 3339 timestamp to verify at. */
|
|
52
|
+
at?: string
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Options for {@link Auths.verifyChain}. */
|
|
56
|
+
export interface VerifyChainOptions {
|
|
57
|
+
/** Array of JSON-serialized attestations (leaf to root). */
|
|
58
|
+
attestations: string[]
|
|
59
|
+
/** Hex-encoded Ed25519 public key of the root identity. */
|
|
60
|
+
rootKey: string
|
|
61
|
+
/** Optional capability the leaf attestation must grant. */
|
|
62
|
+
requiredCapability?: string
|
|
63
|
+
/** Optional witness configuration for receipt-based verification. */
|
|
64
|
+
witnesses?: WitnessConfig
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Primary entry point for all Auths SDK operations.
|
|
69
|
+
*
|
|
70
|
+
* Provides access to identity management, device authorization, signing,
|
|
71
|
+
* verification, policy evaluation, organizations, and more through
|
|
72
|
+
* service properties.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* import { Auths } from '@auths-dev/sdk'
|
|
77
|
+
*
|
|
78
|
+
* const auths = new Auths()
|
|
79
|
+
*
|
|
80
|
+
* // Create an identity
|
|
81
|
+
* const identity = auths.identities.create({ label: 'laptop' })
|
|
82
|
+
*
|
|
83
|
+
* // Sign a message
|
|
84
|
+
* const sig = auths.signAs({
|
|
85
|
+
* message: Buffer.from('hello world'),
|
|
86
|
+
* identityDid: identity.did,
|
|
87
|
+
* })
|
|
88
|
+
* console.log(sig.signature) // hex-encoded Ed25519 signature
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export class Auths {
|
|
92
|
+
/** Path to the Auths Git registry. */
|
|
93
|
+
readonly repoPath: string
|
|
94
|
+
/** Passphrase for key operations, if set. */
|
|
95
|
+
readonly passphrase: string | undefined
|
|
96
|
+
|
|
97
|
+
/** Identity management (create, rotate, delegate agents). */
|
|
98
|
+
readonly identities: IdentityService
|
|
99
|
+
/** Device authorization (link, revoke, extend). */
|
|
100
|
+
readonly devices: DeviceService
|
|
101
|
+
/** Message and action signing. */
|
|
102
|
+
readonly signing: SigningService
|
|
103
|
+
/** Organization management. */
|
|
104
|
+
readonly orgs: OrgService
|
|
105
|
+
/** Trust store for pinned identities. */
|
|
106
|
+
readonly trust: TrustService
|
|
107
|
+
/** Witness node management. */
|
|
108
|
+
readonly witnesses: WitnessService
|
|
109
|
+
/** Attestation queries. */
|
|
110
|
+
readonly attestations: AttestationService
|
|
111
|
+
/** Artifact signing. */
|
|
112
|
+
readonly artifacts: ArtifactService
|
|
113
|
+
/** Git commit signing. */
|
|
114
|
+
readonly commits: CommitService
|
|
115
|
+
/** Repository audit reports. */
|
|
116
|
+
readonly audit: AuditService
|
|
117
|
+
/** Cross-device pairing. */
|
|
118
|
+
readonly pairing: PairingService
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Creates a new Auths client.
|
|
122
|
+
*
|
|
123
|
+
* @param config - Client configuration.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* // Auto-discover (~/.auths)
|
|
128
|
+
* const auths = new Auths()
|
|
129
|
+
*
|
|
130
|
+
* // Explicit configuration
|
|
131
|
+
* const auths = new Auths({
|
|
132
|
+
* repoPath: '/path/to/identity-repo',
|
|
133
|
+
* passphrase: 'my-secret',
|
|
134
|
+
* })
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
constructor(config: ClientConfig = {}) {
|
|
138
|
+
this.repoPath = config.repoPath ?? '~/.auths'
|
|
139
|
+
this.passphrase = config.passphrase
|
|
140
|
+
|
|
141
|
+
this.identities = new IdentityService(this)
|
|
142
|
+
this.devices = new DeviceService(this)
|
|
143
|
+
this.signing = new SigningService(this)
|
|
144
|
+
this.orgs = new OrgService(this)
|
|
145
|
+
this.trust = new TrustService(this)
|
|
146
|
+
this.witnesses = new WitnessService(this)
|
|
147
|
+
this.attestations = new AttestationService(this)
|
|
148
|
+
this.artifacts = new ArtifactService(this)
|
|
149
|
+
this.commits = new CommitService(this)
|
|
150
|
+
this.audit = new AuditService(this)
|
|
151
|
+
this.pairing = new PairingService(this)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Verifies a single attestation with optional capability and time constraints.
|
|
156
|
+
*
|
|
157
|
+
* @param opts - Verification options.
|
|
158
|
+
* @returns The verification result.
|
|
159
|
+
* @throws {@link VerificationError} if verification encounters an error.
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```typescript
|
|
163
|
+
* const result = await auths.verify({
|
|
164
|
+
* attestationJson: json,
|
|
165
|
+
* issuerKey: publicKeyHex,
|
|
166
|
+
* })
|
|
167
|
+
* console.log(result.valid)
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
async verify(opts: VerifyOptions): Promise<VerificationResult> {
|
|
171
|
+
if (opts.at && opts.requiredCapability) {
|
|
172
|
+
return verifyAtTimeWithCapability(opts.attestationJson, opts.issuerKey, opts.at, opts.requiredCapability)
|
|
173
|
+
}
|
|
174
|
+
if (opts.at) {
|
|
175
|
+
return verifyAtTime(opts.attestationJson, opts.issuerKey, opts.at)
|
|
176
|
+
}
|
|
177
|
+
if (opts.requiredCapability) {
|
|
178
|
+
return verifyAttestationWithCapability(opts.attestationJson, opts.issuerKey, opts.requiredCapability)
|
|
179
|
+
}
|
|
180
|
+
return verifyAttestation(opts.attestationJson, opts.issuerKey)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Verifies an attestation chain with optional capability and witness constraints.
|
|
185
|
+
*
|
|
186
|
+
* @param opts - Chain verification options.
|
|
187
|
+
* @returns The verification report.
|
|
188
|
+
* @throws {@link VerificationError} if verification encounters an error.
|
|
189
|
+
*/
|
|
190
|
+
async verifyChain(opts: VerifyChainOptions): Promise<VerificationReport> {
|
|
191
|
+
if (opts.witnesses) {
|
|
192
|
+
return verifyChainWithWitnesses(opts.attestations, opts.rootKey, opts.witnesses)
|
|
193
|
+
}
|
|
194
|
+
if (opts.requiredCapability) {
|
|
195
|
+
return verifyChainWithCapability(opts.attestations, opts.rootKey, opts.requiredCapability)
|
|
196
|
+
}
|
|
197
|
+
return verifyChainFn(opts.attestations, opts.rootKey)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Convenience method to sign a message as an identity.
|
|
202
|
+
*
|
|
203
|
+
* @param opts - Signing options.
|
|
204
|
+
* @returns The signature and signer DID.
|
|
205
|
+
* @throws {@link CryptoError} if signing fails.
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```typescript
|
|
209
|
+
* const result = auths.signAs({
|
|
210
|
+
* message: Buffer.from('hello world'),
|
|
211
|
+
* identityDid: identity.did,
|
|
212
|
+
* })
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
215
|
+
signAs(opts: SignAsIdentityOptions): SignResult {
|
|
216
|
+
return this.signing.signAsIdentity({
|
|
217
|
+
message: opts.message,
|
|
218
|
+
identityDid: opts.identityDid,
|
|
219
|
+
passphrase: opts.passphrase,
|
|
220
|
+
})
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Convenience method to sign an action as an identity.
|
|
225
|
+
*
|
|
226
|
+
* @param opts - Action signing options.
|
|
227
|
+
* @returns The signed action envelope.
|
|
228
|
+
* @throws {@link CryptoError} if signing fails.
|
|
229
|
+
*/
|
|
230
|
+
signActionAs(opts: SignActionAsIdentityOptions): ActionEnvelope {
|
|
231
|
+
return this.signing.signActionAsIdentity({
|
|
232
|
+
actionType: opts.actionType,
|
|
233
|
+
payloadJson: opts.payloadJson,
|
|
234
|
+
identityDid: opts.identityDid,
|
|
235
|
+
passphrase: opts.passphrase,
|
|
236
|
+
})
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Convenience method to sign a message as an agent.
|
|
241
|
+
*
|
|
242
|
+
* @param opts - Agent signing options.
|
|
243
|
+
* @returns The signature and signer DID.
|
|
244
|
+
* @throws {@link CryptoError} if signing fails.
|
|
245
|
+
*/
|
|
246
|
+
signAsAgent(opts: SignAsAgentOptions): SignResult {
|
|
247
|
+
return this.signing.signAsAgent({
|
|
248
|
+
message: opts.message,
|
|
249
|
+
keyAlias: opts.keyAlias,
|
|
250
|
+
passphrase: opts.passphrase,
|
|
251
|
+
})
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Convenience method to sign an action as an agent.
|
|
256
|
+
*
|
|
257
|
+
* @param opts - Agent action signing options.
|
|
258
|
+
* @returns The signed action envelope.
|
|
259
|
+
* @throws {@link CryptoError} if signing fails.
|
|
260
|
+
*/
|
|
261
|
+
signActionAsAgent(opts: SignActionAsAgentOptions): ActionEnvelope {
|
|
262
|
+
return this.signing.signActionAsAgent(opts)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Convenience method to get an identity's public key.
|
|
267
|
+
*
|
|
268
|
+
* @param opts - Lookup options.
|
|
269
|
+
* @returns Hex-encoded Ed25519 public key.
|
|
270
|
+
* @throws {@link CryptoError} if the key cannot be found.
|
|
271
|
+
*/
|
|
272
|
+
getPublicKey(opts: GetPublicKeyOptions): string {
|
|
273
|
+
return this.identities.getPublicKey(opts)
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Runs diagnostics on the Auths installation and returns a report.
|
|
278
|
+
*
|
|
279
|
+
* @returns A human-readable diagnostics string.
|
|
280
|
+
*/
|
|
281
|
+
doctor(): string {
|
|
282
|
+
return native.runDiagnostics(this.repoPath, this.passphrase)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Returns the list of known diagnostic check names.
|
|
287
|
+
*
|
|
288
|
+
* @returns Array of check name strings.
|
|
289
|
+
*/
|
|
290
|
+
static availableChecks(): string[] {
|
|
291
|
+
return ['git_version', 'ssh_keygen', 'git_signing_config']
|
|
292
|
+
}
|
|
293
|
+
}
|
package/lib/commits.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import native from './native'
|
|
2
|
+
import { mapNativeError, CryptoError } from './errors'
|
|
3
|
+
import type { Auths } from './client'
|
|
4
|
+
|
|
5
|
+
/** Result of signing a Git commit. */
|
|
6
|
+
export interface CommitSignResult {
|
|
7
|
+
/** PEM-encoded signature for the commit. */
|
|
8
|
+
signaturePem: string
|
|
9
|
+
/** Signing method identifier. */
|
|
10
|
+
method: string
|
|
11
|
+
/** Namespace for the signature (e.g. `'auths'`). */
|
|
12
|
+
namespace: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Options for {@link CommitService.sign}. */
|
|
16
|
+
export interface SignCommitOptions {
|
|
17
|
+
/** Raw commit data to sign. */
|
|
18
|
+
data: Buffer
|
|
19
|
+
/** DID of the identity to sign with. */
|
|
20
|
+
identityDid: string
|
|
21
|
+
/** Override the client's passphrase. */
|
|
22
|
+
passphrase?: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Signs Git commits using Auths identities.
|
|
27
|
+
*
|
|
28
|
+
* Access via {@link Auths.commits}.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const result = auths.commits.sign({
|
|
33
|
+
* data: commitBuffer,
|
|
34
|
+
* identityDid: identity.did,
|
|
35
|
+
* })
|
|
36
|
+
* console.log(result.signaturePem) // PEM-encoded signature
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export class CommitService {
|
|
40
|
+
constructor(private client: Auths) {}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Signs raw Git commit data, producing a PEM-encoded signature.
|
|
44
|
+
*
|
|
45
|
+
* @param opts - Signing options.
|
|
46
|
+
* @returns The commit signature with method and namespace metadata.
|
|
47
|
+
* @throws {@link CryptoError} if the key is missing or signing fails.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* const result = auths.commits.sign({
|
|
52
|
+
* data: Buffer.from(commitContent),
|
|
53
|
+
* identityDid: identity.did,
|
|
54
|
+
* })
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
sign(opts: SignCommitOptions): CommitSignResult {
|
|
58
|
+
const pp = opts.passphrase ?? this.client.passphrase
|
|
59
|
+
try {
|
|
60
|
+
return native.signCommit(
|
|
61
|
+
opts.data,
|
|
62
|
+
opts.identityDid,
|
|
63
|
+
this.client.repoPath,
|
|
64
|
+
pp,
|
|
65
|
+
)
|
|
66
|
+
} catch (err) {
|
|
67
|
+
throw mapNativeError(err, CryptoError)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
package/lib/devices.ts
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import native from './native'
|
|
2
|
+
import { mapNativeError, IdentityError } from './errors'
|
|
3
|
+
import type { Auths } from './client'
|
|
4
|
+
|
|
5
|
+
/** Result of linking a device to an identity. */
|
|
6
|
+
export interface Device {
|
|
7
|
+
/** The device's DID (typically `did:key:z...`). */
|
|
8
|
+
did: string
|
|
9
|
+
/** Unique identifier of the attestation granting device authorization. */
|
|
10
|
+
attestationId: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Result of extending a device's authorization period. */
|
|
14
|
+
export interface DeviceExtension {
|
|
15
|
+
/** The device's DID. */
|
|
16
|
+
deviceDid: string
|
|
17
|
+
/** New expiration timestamp (RFC 3339). */
|
|
18
|
+
newExpiresAt: string
|
|
19
|
+
/** Previous expiration timestamp, or `null` if there was none. */
|
|
20
|
+
previousExpiresAt: string | null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Options for {@link DeviceService.link}. */
|
|
24
|
+
export interface LinkDeviceOptions {
|
|
25
|
+
/** DID of the identity to link the device under. */
|
|
26
|
+
identityDid: string
|
|
27
|
+
/** Capabilities to grant the device (e.g. `['sign']`). */
|
|
28
|
+
capabilities?: string[]
|
|
29
|
+
/** Optional expiration in days. */
|
|
30
|
+
expiresInDays?: number
|
|
31
|
+
/** Override the client's passphrase. */
|
|
32
|
+
passphrase?: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Options for {@link DeviceService.revoke}. */
|
|
36
|
+
export interface RevokeDeviceOptions {
|
|
37
|
+
/** DID of the device to revoke. */
|
|
38
|
+
deviceDid: string
|
|
39
|
+
/** DID of the identity that authorized the device. */
|
|
40
|
+
identityDid: string
|
|
41
|
+
/** Optional revocation note. */
|
|
42
|
+
note?: string
|
|
43
|
+
/** Override the client's passphrase. */
|
|
44
|
+
passphrase?: string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Options for {@link DeviceService.extend}. */
|
|
48
|
+
export interface ExtendDeviceOptions {
|
|
49
|
+
/** DID of the device to extend. */
|
|
50
|
+
deviceDid: string
|
|
51
|
+
/** DID of the authorizing identity. */
|
|
52
|
+
identityDid: string
|
|
53
|
+
/** Number of days to extend by. Defaults to 90. */
|
|
54
|
+
days?: number
|
|
55
|
+
/** Override the client's passphrase. */
|
|
56
|
+
passphrase?: string
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Manages device authorization lifecycle: link, revoke, and extend.
|
|
61
|
+
*
|
|
62
|
+
* Access via {@link Auths.devices}.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const device = auths.devices.link({
|
|
67
|
+
* identityDid: identity.did,
|
|
68
|
+
* capabilities: ['sign'],
|
|
69
|
+
* expiresInDays: 90,
|
|
70
|
+
* })
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export class DeviceService {
|
|
74
|
+
constructor(private client: Auths) {}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Links a new device to an identity with scoped capabilities.
|
|
78
|
+
*
|
|
79
|
+
* @param opts - Link options.
|
|
80
|
+
* @returns The linked device with its DID and attestation ID.
|
|
81
|
+
* @throws {@link IdentityError} if linking fails.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* const device = auths.devices.link({
|
|
86
|
+
* identityDid: identity.did,
|
|
87
|
+
* capabilities: ['sign'],
|
|
88
|
+
* expiresInDays: 90,
|
|
89
|
+
* })
|
|
90
|
+
* console.log(device.did) // did:key:z...
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
link(opts: LinkDeviceOptions): Device {
|
|
94
|
+
const pp = opts.passphrase ?? this.client.passphrase
|
|
95
|
+
try {
|
|
96
|
+
const result = native.linkDeviceToIdentity(
|
|
97
|
+
opts.identityDid,
|
|
98
|
+
opts.capabilities ?? [],
|
|
99
|
+
this.client.repoPath,
|
|
100
|
+
pp,
|
|
101
|
+
opts.expiresInDays ?? null,
|
|
102
|
+
)
|
|
103
|
+
return {
|
|
104
|
+
did: result.deviceDid,
|
|
105
|
+
attestationId: result.attestationId,
|
|
106
|
+
}
|
|
107
|
+
} catch (err) {
|
|
108
|
+
throw mapNativeError(err, IdentityError)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Revokes a device's authorization under an identity.
|
|
114
|
+
*
|
|
115
|
+
* @param opts - Revocation options.
|
|
116
|
+
* @throws {@link IdentityError} if revocation fails.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* auths.devices.revoke({
|
|
121
|
+
* deviceDid: device.did,
|
|
122
|
+
* identityDid: identity.did,
|
|
123
|
+
* note: 'replaced',
|
|
124
|
+
* })
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
revoke(opts: RevokeDeviceOptions): void {
|
|
128
|
+
const pp = opts.passphrase ?? this.client.passphrase
|
|
129
|
+
try {
|
|
130
|
+
native.revokeDeviceFromIdentity(
|
|
131
|
+
opts.deviceDid,
|
|
132
|
+
opts.identityDid,
|
|
133
|
+
this.client.repoPath,
|
|
134
|
+
pp,
|
|
135
|
+
opts.note ?? null,
|
|
136
|
+
)
|
|
137
|
+
} catch (err) {
|
|
138
|
+
throw mapNativeError(err, IdentityError)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Extends a device's authorization period.
|
|
144
|
+
*
|
|
145
|
+
* @param opts - Extension options.
|
|
146
|
+
* @returns The extension result with new and previous expiration times.
|
|
147
|
+
* @throws {@link IdentityError} if extension fails.
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* const ext = auths.devices.extend({
|
|
152
|
+
* deviceDid: device.did,
|
|
153
|
+
* identityDid: identity.did,
|
|
154
|
+
* days: 60,
|
|
155
|
+
* })
|
|
156
|
+
* console.log(ext.newExpiresAt) // RFC 3339 timestamp
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
extend(opts: ExtendDeviceOptions): DeviceExtension {
|
|
160
|
+
const pp = opts.passphrase ?? this.client.passphrase
|
|
161
|
+
try {
|
|
162
|
+
const result = native.extendDeviceAuthorization(
|
|
163
|
+
opts.deviceDid,
|
|
164
|
+
opts.identityDid,
|
|
165
|
+
opts.days ?? 90,
|
|
166
|
+
this.client.repoPath,
|
|
167
|
+
pp,
|
|
168
|
+
)
|
|
169
|
+
return {
|
|
170
|
+
deviceDid: result.deviceDid,
|
|
171
|
+
newExpiresAt: result.newExpiresAt,
|
|
172
|
+
previousExpiresAt: result.previousExpiresAt ?? null,
|
|
173
|
+
}
|
|
174
|
+
} catch (err) {
|
|
175
|
+
throw mapNativeError(err, IdentityError)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|