Skip to content

Commit

Permalink
better graphs
Browse files Browse the repository at this point in the history
  • Loading branch information
OR13 committed Aug 27, 2024
1 parent 9411be4 commit 388b766
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 99 deletions.
2 changes: 1 addition & 1 deletion src/graph/graph/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const setParam = (
const index = Object.keys(params).length
params[index] = value
const param = '$' + index.toString()
if (moment(value, moment.ISO_8601).isValid()) {
if (typeof value === 'string' && value.includes(':') && moment(value, moment.ISO_8601).isValid()) {
return `datetime(${param})`
}
return param
Expand Down
18 changes: 9 additions & 9 deletions src/graph/graph/jsongraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,6 @@ export type DecodedJwt = {
signature: string
}

// json pointer?

const decodeToken = (token: Uint8Array) => {
const [header, payload, signature] = new TextDecoder().decode(token).split('.')
return {
Expand Down Expand Up @@ -221,18 +219,19 @@ const addLabel = (node: JsonGraphNode, label: string | string[]) => {
const addEnvelopedCredentialToGraph = async (graph: JsonGraph, id: string, object: Record<string, any>, signer: any) => {
const nextId = jose.base64url.encode(await signer.sign(new TextEncoder().encode(object.id)))
const [prefix, token] = object.id.split(';')
const contentType = prefix.replace('data:', '')
addLabel(graph.nodes[object.id], contentType)
const { header, payload } = decodeToken(new TextEncoder().encode(token))
const claimsetId = payload.id || `${nextId}:claims`
addGraphNode({ graph, id: claimsetId })

await addObjectToGraph(graph, object.id, header, signer)
await addObjectToGraph(graph, claimsetId, payload, signer)
addGraphEdge({ graph, source: object.id, label: 'claims', target: claimsetId })

return graph
}



const addArrayToGraph = async (graph: JsonGraph, id: string, array: any[], signer: any, label = 'includes') => {
for (const index in array) {
const item = array[index]
Expand Down Expand Up @@ -297,16 +296,16 @@ const addObjectToGraph = async (graph: JsonGraph, id: string, object: Record<str
}
}

const fromJwt = async (token: Uint8Array) => {
const fromJwt = async (token: Uint8Array, type: string) => {
const { header, payload } = decodeToken(token)
const root = `data:application/jwt;${new TextDecoder().decode(token)}`
const root = `data:${type};${new TextDecoder().decode(token)}`
const signer = await hmac.signer(new TextEncoder().encode(root))
const graph = {
nodes: {},
edges: []
}
addGraphNode({ graph, id: root })
addLabel(graph.nodes[root], 'JWT')
addLabel(graph.nodes[root], type)
const nextId = jose.base64url.encode(await signer.sign(new TextEncoder().encode(root)))
const claimsetId = payload.id || `${nextId}:claims`
addGraphNode({ graph, id: claimsetId })
Expand Down Expand Up @@ -336,10 +335,11 @@ const graph = async (document: Uint8Array, type: string) => {
case 'application/vp-ld+jwt':
case 'application/vp-ld+sd-jwt': {
return annotate(await fromPresentation(tokenToClaimset(document)))
break
}
case 'application/vc+jwt':
case 'application/vp+jwt':
case 'application/jwt': {
return await fromJwt(document)
return await fromJwt(document, type)
}
default: {
throw new Error('Cannot compute graph from unsupported content type: ' + type)
Expand Down
11 changes: 7 additions & 4 deletions src/graph/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const handler = async function ({ positionals, values }: Arguments) {
case 'assist': {
const output = values.output
const graphType = values['graph-type'] || 'application/vnd.jgf+json'
const contentType: any = values['credential-type'] || values['presentation-type']
const contentType: any = values['content-type'] || values['credential-type'] || values['presentation-type']
const verbose = values.verbose || false
const [pathToContent] = positionals
if (verbose) {
Expand All @@ -36,13 +36,16 @@ export const handler = async function ({ positionals, values }: Arguments) {
let allGraphText = ''
const allGraphs = [] as any[]
const api = await getApi()
const { items } = await getPresentations({ sent: true, received: true, api })
let presentations = await getPresentations({ sent: true, received: true, api })
presentations = presentations.items.filter((item) => {
return item.id === 'urn:transmute:presentation:2d05386b-ec60-4f7a-b531-de1d1fd6bfec'
})
const d = await driver()
const session = d.session()
for (const item of items) {
for (const item of presentations) {
try {
const content = encoder.encode(item.content)
graph = await jsongraph.graph(content, 'application/vp-ld+sd-jwt')
graph = await jsongraph.graph(content, 'application/vp+jwt')
allGraphs.push(graph)
const components = await query(graph)
const dangerousQuery = await injection(components)
Expand Down
1 change: 1 addition & 0 deletions tests/fixtures/example.jwt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
18 changes: 15 additions & 3 deletions tests/jsonld2cypher.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ beforeEach(() => {
})


it.only('graph assist with scitt transparent statement', async () => {
await facade(`graph assist ./tests/fixtures/vp.jwt \
--credential-type application/jwt \
it.skip('graph assist with regular jwt', async () => {
await facade(`graph assist ./tests/fixtures/example.jwt \
--content-type application/jwt \
--graph-type application/gql \
--env ./.env \
--verbose --push `)
Expand All @@ -26,3 +26,15 @@ it.only('graph assist with scitt transparent statement', async () => {
expect(secret).toHaveBeenCalledTimes(1)
})

it.skip('graph assist with transmute platform presentations', async () => {
await facade(`graph assist \
--graph-type application/gql \
--env ./.env \
--push `)
expect(debug).toHaveBeenCalledTimes(0)
expect(output).toHaveBeenCalledTimes(1)
expect(secret).toHaveBeenCalledTimes(1)
})



158 changes: 76 additions & 82 deletions tests/vcwg.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,93 +14,87 @@ beforeEach(() => {
secret = jest.spyOn(core, 'setSecret').mockImplementation()
})

// JWT

it('issuer-claims', async () => {
await facade(`vcwg issuer-claims ./tests/fixtures/issuer-claims.json --verbose`)
expect(debug).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})

it('issue-credential', async () => {
await facade(`vcwg issue-credential ./tests/fixtures/private.sig.jwk.json ./tests/fixtures/issuer-claims.yaml --verbose --credential-type application/vc-ld+jwt`)
expect(debug).toHaveBeenCalledTimes(1)
expect(secret).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
describe('application/vc+jwt', () => {
it('issuer-claims', async () => {
await facade(`vcwg issuer-claims ./tests/fixtures/issuer-claims.json --verbose`)
expect(debug).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})
it('issue-credential', async () => {
await facade(`vcwg issue-credential ./tests/fixtures/private.sig.jwk.json ./tests/fixtures/issuer-claims.yaml --verbose --credential-type application/vc-ld+jwt`)
expect(debug).toHaveBeenCalledTimes(1)
expect(secret).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})
it('verify-credential', async () => {
await facade(`vcwg verify-credential ./tests/fixtures/public.sig.jwk.json ./tests/fixtures/issuer-claims.jwt --verbose --credential-type application/vc-ld+jwt`)
expect(debug).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})
it('issue-presentation', async () => {
await facade(`vcwg issue-presentation ./tests/fixtures/private.sig.jwk.json ./tests/fixtures/issuer-claims.jwt --verbose --credential-type application/vc-ld+jwt --presentation-type application/vp-ld+jwt`)
expect(debug).toHaveBeenCalledTimes(1)
expect(secret).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})
it('verify-presentation', async () => {
await facade(`vcwg verify-presentation ./tests/fixtures/public.sig.jwk.json ./tests/fixtures/holder-claims.jwt --verbose --presentation-type application/vp-ld+jwt`)
expect(debug).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})
})

it('verify-credential', async () => {
await facade(`vcwg verify-credential ./tests/fixtures/public.sig.jwk.json ./tests/fixtures/issuer-claims.jwt --verbose --credential-type application/vc-ld+jwt`)
expect(debug).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
describe('application/vc+sd-jwt', () => {
it('issue-credential', async () => {
await facade(`vcwg issue-credential ./tests/fixtures/private.sig.jwk.json ./tests/fixtures/issuer-disclosable-claims.yaml --verbose --credential-type application/vc-ld+sd-jwt`)
expect(debug).toHaveBeenCalledTimes(1)
expect(secret).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})
// skipping because fixtures expire
it.skip('verify-credential', async () => {
await facade(`vcwg verify-credential ./tests/fixtures/public.sig.jwk.json ./tests/fixtures/issuer-disclosable-claims.sd-jwt --verbose --credential-type application/vc-ld+sd-jwt`)
expect(debug).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})
it('issue-presentation', async () => {
await facade(`vcwg issue-presentation ./tests/fixtures/private.sig.jwk.json ./tests/fixtures/issuer-disclosable-claims.sd-jwt ./tests/fixtures/holder-disclosed-claims.yaml --verbose --credential-type application/vc-ld+sd-jwt --presentation-type application/vp-ld+sd-jwt`)
expect(debug).toHaveBeenCalledTimes(1)
expect(secret).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})
// skipping because fixtures expire
it.skip('verify-presentation', async () => {
await facade(`vcwg verify-presentation ./tests/fixtures/public.sig.jwk.json ./tests/fixtures/holder-disclosed-claims.sd-jwt --verbose --presentation-type application/vp-ld+sd-jwt`)
expect(debug).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})
})

it('issue-presentation', async () => {
await facade(`vcwg issue-presentation ./tests/fixtures/private.sig.jwk.json ./tests/fixtures/issuer-claims.jwt --verbose --credential-type application/vc-ld+jwt --presentation-type application/vp-ld+jwt`)
expect(debug).toHaveBeenCalledTimes(1)
expect(secret).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})

it('verify-presentation', async () => {
await facade(`vcwg verify-presentation ./tests/fixtures/public.sig.jwk.json ./tests/fixtures/holder-claims.jwt --verbose --presentation-type application/vp-ld+jwt`)
expect(debug).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})

// SD-JWT

it('issue-credential', async () => {
await facade(`vcwg issue-credential ./tests/fixtures/private.sig.jwk.json ./tests/fixtures/issuer-disclosable-claims.yaml --verbose --credential-type application/vc-ld+sd-jwt`)
expect(debug).toHaveBeenCalledTimes(1)
expect(secret).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})

it('verify-credential', async () => {
await facade(`vcwg verify-credential ./tests/fixtures/public.sig.jwk.json ./tests/fixtures/issuer-disclosable-claims.sd-jwt --verbose --credential-type application/vc-ld+sd-jwt`)
expect(debug).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})

it('issue-presentation', async () => {
await facade(`vcwg issue-presentation ./tests/fixtures/private.sig.jwk.json ./tests/fixtures/issuer-disclosable-claims.sd-jwt ./tests/fixtures/holder-disclosed-claims.yaml --verbose --credential-type application/vc-ld+sd-jwt --presentation-type application/vp-ld+sd-jwt`)
expect(debug).toHaveBeenCalledTimes(1)
expect(secret).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})

it('verify-presentation', async () => {
await facade(`vcwg verify-presentation ./tests/fixtures/public.sig.jwk.json ./tests/fixtures/holder-disclosed-claims.sd-jwt --verbose --presentation-type application/vp-ld+sd-jwt`)
expect(debug).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})

// COSE

it('issue-credential', async () => {
await facade(`vcwg issue-credential ./tests/fixtures/private.sig.jwk.json ./tests/fixtures/issuer-claims.yaml --verbose --credential-type application/vc-ld+cose`)
expect(debug).toHaveBeenCalledTimes(1)
expect(secret).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})

it('verify-credential', async () => {
await facade(`vcwg verify-credential ./tests/fixtures/public.sig.jwk.json ./tests/fixtures/issuer-claims.cbor --verbose --credential-type application/vc-ld+cose`)
expect(debug).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})

it('issue-presentation', async () => {
await facade(`vcwg issue-presentation ./tests/fixtures/private.sig.jwk.json ./tests/fixtures/issuer-claims.cbor --verbose --credential-type application/vc-ld+cose --presentation-type application/vp-ld+cose`)
expect(debug).toHaveBeenCalledTimes(1)
expect(secret).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})

it('verify-presentation', async () => {
await facade(`vcwg verify-presentation ./tests/fixtures/public.sig.jwk.json ./tests/fixtures/holder-claims.cbor --verbose --presentation-type application/vp-ld+cose`)
expect(debug).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
describe('application/vc+cose', () => {
it('issue-credential', async () => {
await facade(`vcwg issue-credential ./tests/fixtures/private.sig.jwk.json ./tests/fixtures/issuer-claims.yaml --verbose --credential-type application/vc-ld+cose`)
expect(debug).toHaveBeenCalledTimes(1)
expect(secret).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})
it('verify-credential', async () => {
await facade(`vcwg verify-credential ./tests/fixtures/public.sig.jwk.json ./tests/fixtures/issuer-claims.cbor --verbose --credential-type application/vc-ld+cose`)
expect(debug).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})
it('issue-presentation', async () => {
await facade(`vcwg issue-presentation ./tests/fixtures/private.sig.jwk.json ./tests/fixtures/issuer-claims.cbor --verbose --credential-type application/vc-ld+cose --presentation-type application/vp-ld+cose`)
expect(debug).toHaveBeenCalledTimes(1)
expect(secret).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})
it('verify-presentation', async () => {
await facade(`vcwg verify-presentation ./tests/fixtures/public.sig.jwk.json ./tests/fixtures/holder-claims.cbor --verbose --presentation-type application/vp-ld+cose`)
expect(debug).toHaveBeenCalledTimes(1)
expect(output).toHaveBeenCalledTimes(1)
})
})

0 comments on commit 388b766

Please sign in to comment.