Skip to content

Commit

Permalink
feat!: update session API (#227)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gozala authored Feb 28, 2023
1 parent 8a578ae commit 9bbb2f7
Show file tree
Hide file tree
Showing 24 changed files with 717 additions and 345 deletions.
2 changes: 1 addition & 1 deletion packages/client/test/fixtures.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as ed25519 from '@ucanto/principal/ed25519'

/** did:key:z6Mkqa4oY9Z5Pf5tUcjLHLUsDjKwMC95HGXdE1j22jkbhz6r */
/** did:key:z6Mkk89bC3JrVqKie71YEcc5M1SMVxuCgNx6zLZ8SYJsxALi */
export const alice = ed25519.parse(
'MgCZT5vOnYZoVAeyjnzuJIVY9J4LNtJ+f8Js0cTPuKUpFne0BVEDJjEu6quFIU8yp91/TY/+MYK8GvlKoTDnqOCovCVM='
)
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/delegation.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import * as UCAN from '@ipld/dag-ucan'
import * as Signature from '@ipld/dag-ucan/signature'
import { from as toPrincipal } from '@ipld/dag-ucan/did'
import * as API from '@ucanto/interface'
import * as Link from './link.js'
import * as CBOR from '@ipld/dag-cbor'
import { sha256 } from 'multiformats/hashes/sha2'

/**
* @deprecated
Expand Down
2 changes: 1 addition & 1 deletion packages/core/test/fixtures.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as ed25519 from '@ucanto/principal/ed25519'

/** did:key:z6Mkqa4oY9Z5Pf5tUcjLHLUsDjKwMC95HGXdE1j22jkbhz6r */
/** did:key:z6Mkk89bC3JrVqKie71YEcc5M1SMVxuCgNx6zLZ8SYJsxALi */
export const alice = ed25519.parse(
'MgCZT5vOnYZoVAeyjnzuJIVY9J4LNtJ+f8Js0cTPuKUpFne0BVEDJjEu6quFIU8yp91/TY/+MYK8GvlKoTDnqOCovCVM='
)
Expand Down
14 changes: 10 additions & 4 deletions packages/interface/src/capability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
export interface Source {
capability: { can: Ability; with: URI; nb?: Caveats }
delegation: Delegation
index: number
}

export interface Match<T = unknown, M extends Match = UnknownMatch>
Expand Down Expand Up @@ -207,13 +206,13 @@ export type InferCreateOptions<R extends Resource, C extends {} | undefined> =
export type InferInvokeOptions<
R extends Resource,
C extends {} | undefined
> = UCANOptions & { issuer: Signer } & InferCreateOptions<R, C>
> = UCANOptions & { issuer: UCAN.Signer } & InferCreateOptions<R, C>

export type InferDelegationOptions<
R extends Resource,
C extends {} | undefined
> = UCANOptions & {
issuer: Signer
issuer: UCAN.Signer
with: R
nb?: Partial<InferCreateOptions<R, C>['nb']>
}
Expand Down Expand Up @@ -414,7 +413,7 @@ export interface DIDKeyResolutionError extends Failure {
readonly name: 'DIDKeyResolutionError'
readonly did: UCAN.DID

readonly cause?: Unauthorized
readonly cause?: Failure
}

export interface Expired extends Failure {
Expand All @@ -436,6 +435,12 @@ export interface InvalidSignature extends Failure {
readonly delegation: Delegation
}

export interface SessionEscalation extends Failure {
readonly name: 'SessionEscalation'
readonly delegation: Delegation
readonly cause: Failure
}

/**
* Error produces by invalid proof
*/
Expand All @@ -444,6 +449,7 @@ export type InvalidProof =
| NotValidBefore
| InvalidSignature
| InvalidAudience
| SessionEscalation
| DIDKeyResolutionError
| UnavailableProof

Expand Down
4 changes: 2 additions & 2 deletions packages/interface/src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export interface DelegationOptions<C extends Capabilities> extends UCANOptions {
* the `audience` {@link Principal}.
*
*/
issuer: Signer
issuer: UCAN.Signer

/**
* The `audience` for a {@link Delegation} is the party being delegated to, or the
Expand Down Expand Up @@ -224,7 +224,7 @@ export interface Invocation<C extends Capability = Capability>
export interface InvocationOptions<C extends Capability = Capability>
extends UCANOptions {
/** The `issuer` of an invocation is the "caller" of the RPC method and the party that signs the invocation UCAN token. */
issuer: Signer
issuer: UCAN.Signer

/** The {@link Capability} that is being invoked. */
capability: C
Expand Down
7 changes: 7 additions & 0 deletions packages/principal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
],
"rsa": [
"dist/src/rsa.d.ts"
],
"account": [
"dist/src/account.d.ts"
]
}
},
Expand All @@ -71,6 +74,10 @@
"./rsa": {
"types": "./dist/src/rsa.d.ts",
"import": "./src/rsa.js"
},
"./account": {
"types": "./dist/src/account.d.ts",
"import": "./src/account.js"
}
},
"c8": {
Expand Down
41 changes: 41 additions & 0 deletions packages/principal/src/absentee.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import * as Signature from '@ipld/dag-ucan/signature'
import * as UCAN from '@ipld/dag-ucan'

/**
* @template {UCAN.DID} ID
* @param {{id: ID }} id
* @returns {UCAN.Signer<ID, Signature.NON_STANDARD>}
*/
export const from = ({ id }) => new Absentee(id)

/**
* An absentee is a special type of signer that produces an absent signature,
* which signals that verifier needs to verify authorization interactively.
*
* @template {UCAN.DID} ID
* @implements {UCAN.Signer<ID, Signature.NON_STANDARD>}
*/
class Absentee {
/**
* @param {ID} id
*/
constructor(id) {
this.id = id
}
did() {
return this.id
}
/* c8 ignore next 3 */
get signatureCode() {
return Signature.NON_STANDARD
}
get signatureAlgorithm() {
return ''
}
sign() {
return Signature.createNonStandard(
this.signatureAlgorithm,
new Uint8Array(0)
)
}
}
1 change: 0 additions & 1 deletion packages/principal/src/ed25519/signer.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ export const from = ({ id, keys }) => {
throw new TypeError(`Unsupported archive format`)
}

from
/**
* @template {API.SignerImporter} O
* @param {O} other
Expand Down
3 changes: 2 additions & 1 deletion packages/principal/src/lib.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as ed25519 from './ed25519.js'
import * as RSA from './rsa.js'
import * as Absentee from './absentee.js'

export const Verifier = ed25519.Verifier.or(RSA.Verifier)
export const Signer = ed25519.or(RSA)

export { ed25519, RSA }
export { ed25519, RSA, Absentee }
17 changes: 17 additions & 0 deletions packages/principal/test/absentee.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Absentee } from '../src/lib.js'
import { assert } from 'chai'

export const utf8 = new TextEncoder()
describe('Absentee', async () => {
it('it can sign', async () => {
const absentee = Absentee.from({ id: 'did:mailto:web.mail:alice' })
assert.deepEqual(absentee.did(), 'did:mailto:web.mail:alice')
assert.deepEqual(absentee.signatureAlgorithm, '')
assert.deepEqual(absentee.signatureCode, 0xd000)

const signature = await absentee.sign(utf8.encode('hello world'))
assert.deepEqual(signature.code, 0xd000)
assert.deepEqual(signature.algorithm, '')
assert.deepEqual(signature.raw, new Uint8Array())
})
})
2 changes: 1 addition & 1 deletion packages/server/test/fixtures.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as ed25519 from '@ucanto/principal/ed25519'

/** did:key:z6Mkqa4oY9Z5Pf5tUcjLHLUsDjKwMC95HGXdE1j22jkbhz6r */
/** did:key:z6Mkk89bC3JrVqKie71YEcc5M1SMVxuCgNx6zLZ8SYJsxALi */
export const alice = ed25519.parse(
'MgCZT5vOnYZoVAeyjnzuJIVY9J4LNtJ+f8Js0cTPuKUpFne0BVEDJjEu6quFIU8yp91/TY/+MYK8GvlKoTDnqOCovCVM='
)
Expand Down
2 changes: 1 addition & 1 deletion packages/transport/test/fixtures.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as ed25519 from '@ucanto/principal/ed25519'

/** did:key:z6Mkqa4oY9Z5Pf5tUcjLHLUsDjKwMC95HGXdE1j22jkbhz6r */
/** did:key:z6Mkk89bC3JrVqKie71YEcc5M1SMVxuCgNx6zLZ8SYJsxALi */
export const alice = ed25519.parse(
'MgCZT5vOnYZoVAeyjnzuJIVY9J4LNtJ+f8Js0cTPuKUpFne0BVEDJjEu6quFIU8yp91/TY/+MYK8GvlKoTDnqOCovCVM='
)
Expand Down
31 changes: 26 additions & 5 deletions packages/validator/src/error.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,30 @@ export class DelegationError extends Failure {
}
}

/**
* @implements {API.SessionEscalation}
*/
export class SessionEscalation extends Failure {
/**
* @param {object} source
* @param {API.Delegation} source.delegation
* @param {API.Failure} source.cause
*/
constructor({ delegation, cause }) {
super()
this.name = the('SessionEscalation')
this.delegation = delegation
this.cause = cause
}
describe() {
const issuer = this.delegation.issuer.did()
return [
`Delegation ${this.delegation.cid} issued by ${issuer} has an invalid session`,
li(this.cause.message),
].join('\n')
}
}

/**
* @implements {API.InvalidSignature}
*/
Expand Down Expand Up @@ -145,7 +169,7 @@ export class UnavailableProof extends Failure {
export class DIDKeyResolutionError extends Failure {
/**
* @param {API.UCAN.DID} did
* @param {API.Unauthorized} [cause]
* @param {API.Failure} [cause]
*/
constructor(did, cause) {
super()
Expand All @@ -154,10 +178,7 @@ export class DIDKeyResolutionError extends Failure {
this.cause = cause
}
describe() {
return [
`Unable to resolve '${this.did}' key`,
...(this.cause ? [li(`Resolution failed: ${this.cause.message}`)] : []),
].join('\n')
return `Unable to resolve '${this.did}' key`
}
}

Expand Down
Loading

0 comments on commit 9bbb2f7

Please sign in to comment.