-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
221 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
pub mod token; | ||
pub mod verify; | ||
|
||
pub type JsResult<T> = Result<T, js_sys::Error>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
use crate::ucan::JsResult; | ||
use ::ucan::{capability::CapabilityIpld, Ucan as RsUcan}; | ||
use base64::Engine; | ||
use js_sys::Error; | ||
use serde::{Deserialize, Serialize}; | ||
use serde_json::Value; | ||
use serde_wasm_bindgen::Serializer; | ||
use wasm_bindgen::prelude::wasm_bindgen; | ||
|
||
#[wasm_bindgen(typescript_custom_section)] | ||
const UCAN: &'static str = r#" | ||
interface Ucan { | ||
header: { | ||
alg: string, | ||
typ: string, | ||
ucv: string | ||
}, | ||
payload: { | ||
iss: string, | ||
aud: string, | ||
exp: number, | ||
nbf?: number, | ||
nnc?: string, | ||
att: unknown[], | ||
fct?: Record<string,unknown>[], | ||
prf?: string[] | ||
} | ||
signature: string | ||
} | ||
"#; | ||
|
||
#[wasm_bindgen] | ||
extern "C" { | ||
#[wasm_bindgen(typescript_type = "Ucan")] | ||
pub type Ucan; | ||
} | ||
|
||
#[wasm_bindgen] | ||
#[derive(Debug, Serialize, Deserialize)] | ||
pub struct ResolvedUcan { | ||
header: Header, | ||
payload: Payload, | ||
signature: String, | ||
} | ||
|
||
#[wasm_bindgen] | ||
#[derive(Debug, Serialize, Deserialize)] | ||
pub struct Header { | ||
alg: String, | ||
typ: String, | ||
ucv: String, | ||
} | ||
|
||
#[wasm_bindgen] | ||
#[derive(Debug, Serialize, Deserialize)] | ||
pub struct Payload { | ||
iss: String, | ||
aud: String, | ||
exp: u64, | ||
nbf: Option<u64>, | ||
nnc: Option<String>, | ||
att: Vec<CapabilityIpld>, | ||
fct: Option<Vec<Value>>, | ||
prf: Option<Vec<String>>, | ||
} | ||
|
||
/// Decode a UCAN | ||
#[wasm_bindgen(js_name = "decode")] | ||
pub async fn decode(token: String) -> JsResult<Ucan> { | ||
let ucan = RsUcan::try_from(token).map_err(|e| Error::new(&format!("{e}")))?; | ||
|
||
let header = Header { | ||
alg: ucan.algorithm().into(), | ||
typ: "JWT".into(), | ||
ucv: ucan.version().into(), | ||
}; | ||
|
||
let payload = Payload { | ||
iss: ucan.issuer().into(), | ||
aud: ucan.audience().into(), | ||
exp: *ucan.expires_at(), | ||
nbf: *ucan.not_before(), | ||
nnc: ucan.nonce().clone(), | ||
att: ucan.attenuation().to_vec(), | ||
fct: ucan.facts().clone(), | ||
prf: ucan.proofs().clone(), | ||
}; | ||
|
||
let signature = base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(ucan.signature()); | ||
|
||
let resolved = ResolvedUcan { | ||
header, | ||
payload, | ||
signature, | ||
}; | ||
|
||
let serializer = Serializer::new().serialize_maps_as_objects(true); | ||
let value = resolved.serialize(&serializer).unwrap(); | ||
|
||
Ok(Ucan { obj: value }) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,36 @@ | ||
[ | ||
{ | ||
"comment": "UCAN is valid", | ||
"token": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCIsInVjdiI6IjAuOS4wLWNhbmFyeSJ9.eyJhdHQiOlt7ImNhbiI6ImVtYWlsL3NlbmQiLCJuYiI6bnVsbCwid2l0aCI6Im1haWx0bzphbGljZUBlbWFpbC5jb20ifV0sImF1ZCI6ImRpZDprZXk6ejZNa3RhZlpUUkVqSmt2VjVtZkp4Y0xwTkJvVlB3RExoVHVNZzluZzdkWTR6TUFMIiwiZXhwIjo5MjQ2MjExMjAwLCJmY3QiOlt7ImNoYWxsZW5nZSI6ImFiY2RlZiJ9XSwiaXNzIjoiZGlkOmtleTp6Nk1rZmZEWkNrQ1RXcmVnODg2OGZHMUZHRm9nY0pqNVg2UFk5M3BQY1dEbjlib2IiLCJwcmYiOlsiYmFma3I0aWdmM3N6N2tqNWRoeHJkanVmeHZhdmtraW5wazJpNzNpNXBzdXA2Y3h1dmR5bTJqZWN3MmUiXX0.nTJl6kKrEKYzp6D4tTc-xYgNxH4urv8tfGU7so6ZIf5s86yMnb6bLpSPMeRchbOafVIy9vil9vjjYACzY1GvBg", | ||
"assertions": { | ||
"header": { | ||
"alg": "EdDSA", | ||
"typ": "JWT", | ||
"ucv": "0.9.0-canary" | ||
}, | ||
"payload": { | ||
"iss": "did:key:z6MkffDZCkCTWreg8868fG1FGFogcJj5X6PY93pPcWDn9bob", | ||
"aud": "did:key:z6MktafZTREjJkvV5mfJxcLpNBoVPwDLhTuMg9ng7dY4zMAL", | ||
"exp": 9246211200, | ||
"fct": [ | ||
{ | ||
"challenge": "abcdef" | ||
} | ||
], | ||
"att": [ | ||
{ | ||
"can": "email/send", | ||
"nb": null, | ||
"with": "mailto:[email protected]" | ||
} | ||
], | ||
"prf": [ | ||
"bafkr4igf3sz7kj5dhxrdjufxvavkkinpk2i73i5psup6cxuvdym2jecw2e" | ||
] | ||
}, | ||
"signature": "nTJl6kKrEKYzp6D4tTc-xYgNxH4urv8tfGU7so6ZIf5s86yMnb6bLpSPMeRchbOafVIy9vil9vjjYACzY1GvBg" | ||
} | ||
}, | ||
{ | ||
"comment": "UCAN has not expired", | ||
"token": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCIsInVjdiI6IjAuOS4wLWNhbmFyeSJ9.eyJhdHQiOltdLCJhdWQiOiJkaWQ6a2V5Ono2TWtmZkRaQ2tDVFdyZWc4ODY4ZkcxRkdGb2djSmo1WDZQWTkzcFBjV0RuOWJvYiIsImV4cCI6OTI0NjIxMTIwMCwiZmN0IjpbXSwiaXNzIjoiZGlkOmtleTp6Nk1razg5YkMzSnJWcUtpZTcxWUVjYzVNMVNNVnh1Q2dOeDZ6TFo4U1lKc3hBTGkiLCJwcmYiOltdfQ.l-OlVJ8sNv6dHcROAL1wkMZ3JMCGx-o4F9-sSycMtEikj1J1DTlVNep1J5zKR6sEniyFa__8zwrWydtHZyglCQ", | ||
|
@@ -15,7 +47,8 @@ | |
"fct": [], | ||
"att": [], | ||
"prf": [] | ||
} | ||
}, | ||
"signature": "l-OlVJ8sNv6dHcROAL1wkMZ3JMCGx-o4F9-sSycMtEikj1J1DTlVNep1J5zKR6sEniyFa__8zwrWydtHZyglCQ" | ||
} | ||
}, | ||
{ | ||
|
@@ -35,7 +68,8 @@ | |
"fct": [], | ||
"att": [], | ||
"prf": [] | ||
} | ||
}, | ||
"signature": "-8duL-fCdG-2hEbe4F6hqE-g2Tf6II-jBzb8qKAbp41snlHvPYpvoPAC4HobmtTodFDQXdmI7u_mbQhesGHTAw" | ||
} | ||
}, | ||
{ | ||
|
@@ -54,7 +88,8 @@ | |
"fct": [], | ||
"att": [], | ||
"prf": [] | ||
} | ||
}, | ||
"signature": "l-OlVJ8sNv6dHcROAL1wkMZ3JMCGx-o4F9-sSycMtEikj1J1DTlVNep1J5zKR6sEniyFa__8zwrWydtHZyglCQ" | ||
} | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import assert from 'assert' | ||
import { getFixture } from '../fixtures/index.js' | ||
|
||
// The Ucan type is the same across browser and node environments | ||
import type { Ucan } from '../../lib/browser/ucan_wasm.js' | ||
|
||
export function runTokenTests( | ||
impl: { | ||
runner?: { describe, it }, | ||
ucan: { | ||
decode: (token: string) => Promise<Ucan> | ||
} | ||
}) { | ||
|
||
// Use runner or fallback to implicit mocha implementations | ||
const describe = impl.runner?.describe ?? globalThis.describe | ||
const it = impl.runner?.it ?? globalThis.it | ||
|
||
const { decode } = impl.ucan | ||
|
||
describe('decode', async () => { | ||
it('should decode a token', async () => { | ||
const valid = getFixture('valid', 'UCAN is valid') | ||
const ucan = await decode(valid.token) | ||
|
||
// Check header | ||
assert.equal(ucan.header.alg, valid.assertions.header.alg) | ||
assert.equal(ucan.header.typ, valid.assertions.header.typ) | ||
assert.equal(ucan.header.ucv, valid.assertions.header.ucv) | ||
|
||
// Check payload | ||
assert.equal(ucan.payload.iss, valid.assertions.payload.iss) | ||
assert.equal(ucan.payload.aud, valid.assertions.payload.aud) | ||
assert.equal(ucan.payload.exp, valid.assertions.payload.exp) | ||
assert.equal(ucan.payload.nbf, valid.assertions.payload.nbf) | ||
assert.equal(ucan.payload.nnc, valid.assertions.payload.nnc) | ||
assert.deepEqual(ucan.payload.att, valid.assertions.payload.att) | ||
assert.deepEqual(ucan.payload.fct, valid.assertions.payload.fct) | ||
assert.deepEqual(ucan.payload.prf, valid.assertions.payload.prf) | ||
|
||
// Check signature | ||
assert.equal(ucan.signature, valid.assertions.signature) | ||
}) | ||
}) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters