Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
64f9c96
Init livekit-uniffi crate
ladvoc Oct 16, 2025
9f85820
Configure
ladvoc Oct 16, 2025
24110d9
Expose access token module
ladvoc Oct 16, 2025
794c5d2
Add placeholder config file
ladvoc Oct 16, 2025
5736d45
Allow omitting token options
ladvoc Oct 16, 2025
ea7a068
Add python test
ladvoc Oct 16, 2025
310b632
Use fully qualified names for macros
ladvoc Oct 18, 2025
627b91f
Don't commit dylib and pycache
ladvoc Oct 18, 2025
eef2ad7
Implement log forwarding
ladvoc Oct 18, 2025
734245e
Expose build info
ladvoc Oct 19, 2025
5fbdedd
Allow multiple invocations
ladvoc Oct 21, 2025
c658395
Change log level in example
ladvoc Oct 21, 2025
82f38c8
Remove debug
ladvoc Oct 21, 2025
f0173ba
Introduce Makefile
ladvoc Nov 19, 2025
df14e25
License check
ladvoc Nov 20, 2025
b3835e3
Handle multi-platform builds
ladvoc Nov 20, 2025
e07b2d5
Regenerate bindings
ladvoc Nov 20, 2025
48385c5
Update README
ladvoc Nov 20, 2025
c004438
Fix typo
ladvoc Nov 20, 2025
ba06af5
Format
ladvoc Nov 20, 2025
3faab50
Parse unverified JWT (#756)
pblazej Nov 3, 2025
bc14007
Fix tier3 warnings
pblazej Nov 20, 2025
8612dd0
Move to cargo-swift
pblazej Dec 11, 2025
0249813
Merge branch 'main' into ladvoc/uniffi-trial
pblazej Dec 11, 2025
c6a5f55
Expose room config
pblazej Dec 11, 2025
3f9e0fd
Platforms
pblazej Dec 12, 2025
347b046
Local Package.swift
pblazej Dec 12, 2025
5c5af74
Remote Package.swift
pblazej Dec 12, 2025
4d82c9d
Fmt
pblazej Dec 12, 2025
5a4283a
Remove packages and generated code
pblazej Dec 12, 2025
e1df4af
Readme
pblazej Dec 12, 2025
729bc10
Static lib
pblazej Dec 12, 2025
af133b4
feat: add node bindgen packaging code
1egoman Dec 12, 2025
e9e72c1
fix: swap license header block format to please hawkeye
1egoman Dec 12, 2025
5f0c9da
fix: remove undefined fields thanks to https://github.com/livekit/uni…
1egoman Dec 12, 2025
24cffd6
Workaround for cargo-swift vs newest Swift
pblazej Dec 18, 2025
8e85216
Workaround the other way around
pblazej Dec 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
310 changes: 310 additions & 0 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"livekit-api",
"livekit-protocol",
"livekit-ffi",
"livekit-uniffi",
"livekit-runtime",
"libwebrtc",
"soxr-sys",
Expand All @@ -26,7 +27,7 @@ members = [
"examples/screensharing",
"examples/send_bytes",
"examples/webhooks",
"examples/wgpu_room",
"examples/wgpu_room"
]

[workspace.dependencies]
Expand Down
2 changes: 2 additions & 0 deletions licenserc.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ excludes = [
"NOTICE",
".github",
"*.toml",
"!Makefile.toml",
"*.txt",
# Generated files
"livekit-protocol/src/livekit.rs",
"livekit-protocol/src/livekit.serde.rs",
"livekit-uniffi/packages"
]

[mapping.DOUBLESLASH_STYLE]
Expand Down
66 changes: 61 additions & 5 deletions livekit-api/src/access_token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,21 @@ pub struct Claims {
pub room_config: Option<livekit_protocol::RoomConfiguration>,
}

impl Claims {
pub fn from_unverified(token: &str) -> Result<Self, AccessTokenError> {
let mut validation = jsonwebtoken::Validation::new(jsonwebtoken::Algorithm::HS256);
validation.validate_exp = true;
validation.validate_nbf = true;
validation.set_required_spec_claims::<String>(&[]);
validation.insecure_disable_signature_validation();

let token =
jsonwebtoken::decode::<Claims>(token, &DecodingKey::from_secret(&[]), &validation)?;

Ok(token.claims)
}
}

#[derive(Clone)]
pub struct AccessToken {
api_key: String,
Expand Down Expand Up @@ -299,10 +314,6 @@ impl TokenVerifier {
pub fn verify(&self, token: &str) -> Result<Claims, AccessTokenError> {
let mut validation = jsonwebtoken::Validation::new(jsonwebtoken::Algorithm::HS256);
validation.validate_exp = true;
#[cfg(test)] // FIXME: TEST_TOKEN is expired, TODO: generate TEST_TOKEN at test runtime
{
validation.validate_exp = false;
}
validation.validate_nbf = true;
validation.set_issuer(&[&self.api_key]);

Expand All @@ -320,7 +331,7 @@ impl TokenVerifier {
mod tests {
use std::time::Duration;

use super::{AccessToken, TokenVerifier, VideoGrants};
use super::{AccessToken, Claims, TokenVerifier, VideoGrants};

const TEST_API_KEY: &str = "myapikey";
const TEST_API_SECRET: &str = "thiskeyistotallyunsafe";
Expand Down Expand Up @@ -383,4 +394,49 @@ mod tests {
claims
);
}

#[test]
fn test_unverified_token() {
let claims = Claims::from_unverified(TEST_TOKEN).expect("Failed to parse token");

assert_eq!(claims.sub, "identity");
assert_eq!(claims.name, "name");
assert_eq!(claims.iss, TEST_API_KEY);
assert_eq!(
claims.room_config,
Some(livekit_protocol::RoomConfiguration {
agents: vec![livekit_protocol::RoomAgentDispatch {
agent_name: "test-agent".to_string(),
metadata: "test-metadata".to_string(),
}],
..Default::default()
})
);

let token = AccessToken::with_api_key(TEST_API_KEY, TEST_API_SECRET)
.with_ttl(Duration::from_secs(60))
.with_identity("test")
.with_name("test")
.with_grants(VideoGrants {
room_join: true,
room: "test-room".to_string(),
..Default::default()
})
.to_jwt()
.unwrap();

let claims = Claims::from_unverified(&token).expect("Failed to parse fresh token");
assert_eq!(claims.sub, "test");
assert_eq!(claims.name, "test");
assert_eq!(claims.video.room, "test-room");
assert!(claims.video.room_join);

let parts: Vec<&str> = token.split('.').collect();
let malformed_token = format!("{}.{}.wrongsignature", parts[0], parts[1]);

let claims = Claims::from_unverified(&malformed_token)
.expect("Failed to parse token with wrong signature");
assert_eq!(claims.sub, "test");
assert_eq!(claims.name, "test");
}
}
2 changes: 1 addition & 1 deletion livekit-api/src/test_token.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoibmFtZSIsInZpZGVvIjp7InJvb21Kb2luIjp0cnVlLCJyb29tIjoibXktcm9vbSIsImNhblB1Ymxpc2giOnRydWUsImNhblN1YnNjcmliZSI6dHJ1ZSwiY2FuUHVibGlzaERhdGEiOnRydWV9LCJyb29tQ29uZmlnIjp7ImFnZW50cyI6W3siYWdlbnROYW1lIjoidGVzdC1hZ2VudCIsIm1ldGFkYXRhIjoidGVzdC1tZXRhZGF0YSJ9XX0sInN1YiI6ImlkZW50aXR5IiwiaXNzIjoibXlhcGlrZXkiLCJuYmYiOjE3NDE4Njk2NzksImV4cCI6MTc0MTg5MTI3OX0.9_eOcZ1RNaRXxwdU36LTYoxsHtv_IhfhLk-kTd8MDY4
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoibmFtZSIsInZpZGVvIjp7InJvb21Kb2luIjp0cnVlLCJyb29tIjoibXktcm9vbSIsImNhblB1Ymxpc2giOnRydWUsImNhblN1YnNjcmliZSI6dHJ1ZSwiY2FuUHVibGlzaERhdGEiOnRydWV9LCJyb29tQ29uZmlnIjp7ImFnZW50cyI6W3siYWdlbnROYW1lIjoidGVzdC1hZ2VudCIsIm1ldGFkYXRhIjoidGVzdC1tZXRhZGF0YSJ9XX0sInN1YiI6ImlkZW50aXR5IiwiaXNzIjoibXlhcGlrZXkiLCJuYmYiOjE3NDE4Njk2NzksImV4cCI6NDEwMjQ0NDgwMH0.hmKovgw6sDbQUFZxAQ9Xjb9-VUzeBw1A6URTXFuCLMU
2 changes: 2 additions & 0 deletions livekit-uniffi/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
generated/
packages/
34 changes: 34 additions & 0 deletions livekit-uniffi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[lib]
crate-type = ["cdylib", "staticlib", "lib"]

[package]
name = "livekit-uniffi"
version = "0.1.0"
edition = "2021"
license = "Apache-2.0"
description = "Experimental FFI interface using UniFFI"
repository = "https://github.com/livekit/rust-sdks"
readme = "README.md"

[dependencies]
livekit-protocol = { workspace = true }
livekit-api = { workspace = true }
uniffi = { version = "0.30.0", features = ["cli", "scaffolding-ffi-buffer-fns"] }
log = "0.4.28"
tokio = { version = "1.48.0", features = ["sync"] }
once_cell = "1.21.3"

[build-dependencies]
uniffi = { version = "0.30.0", features = ["build", "scaffolding-ffi-buffer-fns"] }

[[bin]]
name = "uniffi-bindgen"
path = "bindgen.rs"

[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"
strip = "symbols"
debug = false
Loading
Loading