diff --git a/.env.production b/.env.production index 6e98582..e52e0d1 100644 --- a/.env.production +++ b/.env.production @@ -1,3 +1,5 @@ PUBLIC_RELAY_SCHEME="https" PUBLIC_RELAY_HOST="relay.quic.video" -PUBLIC_DEMO_TOKEN="" + +# cargo run --bin moq-token -- --key root.jwk sign --path "demo" --subscribe "" > demo.jwt +PUBLIC_DEMO_TOKEN="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwYXRoIjoiZGVtbyIsInB1YiI6bnVsbCwicHViISI6bnVsbCwic3ViIjoiIiwiZXhwIjpudWxsLCJpYXQiOm51bGx9.xeSMuPLRqmjkRLtcraXnvwqmYDK_BuU2ooZOWisL_aE" diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index d9f046d..2ab68bb 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -18,7 +18,5 @@ jobs: with: cache: 'pnpm' - - uses: biomejs/setup-biome@v2 - - run: pnpm install --frozen-lockfile - run: pnpm run check diff --git a/.gitignore b/.gitignore index 559ecda..22399fa 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,6 @@ bun.lockb .DS_Store # Don't leak me secrets -.env.production \ No newline at end of file +.env.production +*.jwt +*.jwk diff --git a/biome.json b/biome.json index 323aecd..e156a6e 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "$schema": "https://biomejs.dev/schemas/2.0.5/schema.json", "vcs": { "enabled": true, "clientKind": "git", @@ -13,13 +13,23 @@ "indentStyle": "tab", "lineWidth": 120 }, - "organizeImports": { - "enabled": true - }, + "assist": { "actions": { "source": { "organizeImports": "on" } } }, "linter": { "enabled": true, "rules": { - "recommended": true + "recommended": true, + "style": { + "noParameterAssign": "error", + "useAsConstAssertion": "error", + "useDefaultParameterLast": "error", + "useEnumInitializers": "error", + "useSelfClosingElements": "error", + "useSingleVarDeclarator": "error", + "noUnusedTemplateLiteral": "error", + "useNumberNamespace": "error", + "noInferrableTypes": "error", + "noUselessElse": "error" + } } }, "javascript": { diff --git a/infra/input.tf b/infra/input.tf index a39ed63..03ca954 100644 --- a/infra/input.tf +++ b/infra/input.tf @@ -20,34 +20,31 @@ variable "domain" { variable "docker_relay" { description = "Docker image for moq-relay" - default = "docker.io/kixelated/moq-relay:latest" + default = "docker.io/kixelated/moq-relay:0.7.5" } variable "docker_hang" { description = "Docker image for hang" - default = "docker.io/kixelated/hang:latest" + default = "docker.io/kixelated/hang:0.1.7" } -# A key generated using moq-token generate -variable "demo_key" { - description = "demo key" +# cargo run --bin moq-token -- --key root.jwk generate +variable "root_key" { + description = "root key" sensitive = true } # A token used to publish demo/bbb.hang # This is very manual/crude, but I don't want someone to hijack the broadcast. +# cargo run --bin moq-token -- --key root.jwk sign --path "demo" --publish "" > demo.jwt variable "demo_token" { description = "demo token" sensitive = true } -variable "root_key" { - description = "root key" - sensitive = true -} - -variable "root_token" { - description = "root token" +# cargo run --bin moq-token -- --key root.jwk sign --publish "" --publish-secondary --subscribe "" --subscribe-primary > cluster.jwt +variable "cluster_token" { + description = "cluster token" sensitive = true } @@ -60,18 +57,18 @@ locals { machine = "t2d-standard-1", image = "cos-cloud/cos-stable", }, - #europe-west = { # Netherlands - # region = "europe-west4", - # zone = "europe-west4-b", - # machine = "t2d-standard-1", - # image = "cos-cloud/cos-stable", - #}, - #asia-southeast = { # Singapore - # region = "asia-southeast1", - # zone = "asia-southeast1-c", - # machine = "t2d-standard-1", - # image = "cos-cloud/cos-stable", - #} + europe-west = { # Netherlands + region = "europe-west4", + zone = "europe-west4-b", + machine = "t2d-standard-1", + image = "cos-cloud/cos-stable", + }, + asia-southeast = { # Singapore + region = "asia-southeast1", + zone = "asia-southeast1-c", + machine = "t2d-standard-1", + image = "cos-cloud/cos-stable", + }, } pub = { region = "us-central1" diff --git a/infra/pub.yml.tpl b/infra/pub.yml.tpl index d584f93..13c6aab 100644 --- a/infra/pub.yml.tpl +++ b/infra/pub.yml.tpl @@ -20,7 +20,7 @@ write_files: -e REGION=${region} \ --entrypoint hang-bbb \ ${docker_image} \ - publish "https://relay.quic.video/demo/bbb.hang" + publish "https://relay.quic.video/${demo_token}.jwt" ExecStop=docker stop hang-bbb @@ -51,4 +51,4 @@ write_files: runcmd: - systemctl daemon-reload - systemctl restart docker - - systemctl start hang-bbb moq-clock + - systemctl start hang-bbb diff --git a/infra/relay.tf b/infra/relay.tf index 2b84b18..fda7219 100644 --- a/infra/relay.tf +++ b/infra/relay.tf @@ -47,12 +47,9 @@ resource "google_compute_instance" "relay" { cluster_node = "relay-${each.key}.${each.value.zone}.c.${var.project}.internal" cluster_root = "${local.root}.c.${var.project}.internal" - # The demo key, used to authenticate the demo broadcast - demo_key = var.demo_key - # The root key and token, used to authenticate nodes - root_key = var.root_key - root_token = var.root_token + root_key = var.root_key + cluster_token = var.cluster_token }) } diff --git a/infra/relay.yml.tpl b/infra/relay.yml.tpl index 9bfdf6f..376df5e 100644 --- a/infra/relay.yml.tpl +++ b/infra/relay.yml.tpl @@ -37,13 +37,6 @@ write_files: permissions: "0644" owner: root - # Write the demo key to disk - - path: /etc/moq/demo.jwk - content: | - ${indent(6, demo_key)} - permissions: "0644" - owner: root - # Write the root key to disk - path: /etc/moq/root.jwk content: | @@ -52,9 +45,9 @@ write_files: owner: root # Write the root token to disk - - path: /etc/moq/root.jwt + - path: /etc/moq/cluster.jwt content: | - ${indent(6, root_token)} + ${indent(6, cluster_token)} permissions: "0644" owner: root @@ -77,14 +70,14 @@ write_files: [cluster] connect = "${cluster_root}" advertise = "${cluster_node}" - token = "/etc/moq/root.jwk" + token = "/etc/moq/cluster.jwt" [auth] key = "/etc/moq/root.jwk" [auth.path] - demo = "" anon = "" + hang = "" permissions: "0644" owner: root diff --git a/package.json b/package.json index 53b98d3..c518e3c 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "dev": "astro dev --open", "build": "astro build --production", - "prod": "astro build --production && astro preview --production", + "prod": "astro build --production && astro preview --production --open", "check": "biome ci && tsc --noEmit", "fix": "biome check --write && pnpm audit fix" }, @@ -15,7 +15,7 @@ "@astrojs/node": "9.2.2", "@astrojs/solid-js": "5.1.0", "@astrojs/tailwind": "6.0.2", - "@kixelated/hang": "^0.2.1", + "@kixelated/hang": "^0.2.5", "@tailwindcss/forms": "^0.5.10", "@tailwindcss/typography": "^0.5.16", "astro": "^5.8.2", @@ -27,6 +27,7 @@ "vite-plugin-wasm": "^3.4.1" }, "devDependencies": { + "@biomejs/biome": "2.0.5", "@types/node": "^22.15.29" }, "packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 794f39c..e1c3434 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,8 +21,8 @@ importers: specifier: 6.0.2 version: 6.0.2(astro@5.8.2(@types/node@22.15.29)(jiti@1.21.7)(rollup@4.41.1)(typescript@5.8.3)(yaml@2.8.0))(tailwindcss@3.4.17) '@kixelated/hang': - specifier: ^0.2.1 - version: 0.2.1 + specifier: ^0.2.5 + version: 0.2.5(@types/react@19.1.8)(solid-js@1.9.7) '@tailwindcss/forms': specifier: ^0.5.10 version: 0.5.10(tailwindcss@3.4.17) @@ -51,6 +51,9 @@ importers: specifier: ^3.4.1 version: 3.4.1(vite@6.3.5(@types/node@22.15.29)(jiti@1.21.7)(yaml@2.8.0)) devDependencies: + '@biomejs/biome': + specifier: 2.0.5 + version: 2.0.5 '@types/node': specifier: ^22.15.29 version: 22.15.29 @@ -186,6 +189,59 @@ packages: resolution: {integrity: sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==} engines: {node: '>=6.9.0'} + '@biomejs/biome@2.0.5': + resolution: {integrity: sha512-MztFGhE6cVjf3QmomWu83GpTFyWY8KIcskgRf2AqVEMSH4qI4rNdBLdpAQ11TNK9pUfLGz3IIOC1ZYwgBePtig==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@2.0.5': + resolution: {integrity: sha512-VIIWQv9Rcj9XresjCf3isBFfWjFStsdGZvm8SmwJzKs/22YQj167ge7DkxuaaZbNf2kmYif0AcjAKvtNedEoEw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@2.0.5': + resolution: {integrity: sha512-DRpGxBgf5Z7HUFcNUB6n66UiD4VlBlMpngNf32wPraxX8vYU6N9cb3xQWOXIQVBBQ64QfsSLJnjNu79i/LNmSg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@2.0.5': + resolution: {integrity: sha512-OpflTCOw/ElEs7QZqN/HFaSViPHjAsAPxFJ22LhWUWvuJgcy/Z8+hRV0/3mk/ZRWy5A6fCDKHZqAxU+xB6W4mA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@2.0.5': + resolution: {integrity: sha512-FQTfDNMXOknf8+g9Eede2daaduRjTC2SNbfWPNFMadN9K3UKjeZ62jwiYxztPaz9zQQsZU8VbddQIaeQY5CmIA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@2.0.5': + resolution: {integrity: sha512-9lmjCnajAzpZXbav2P6D87ugkhnaDpJtDvOH5uQbY2RXeW6Rq18uOUltxgacGBP+d8GusTr+s3IFOu7SN0Ok8g==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@2.0.5': + resolution: {integrity: sha512-znpfydUDPuDkyBTulnODrQVK2FaG/4hIOPcQSsF2GeauQOYrBAOplj0etGB0NUrr0dFsvaQ15nzDXYb60ACoiw==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@2.0.5': + resolution: {integrity: sha512-CP2wKQB+gh8HdJTFKYRFETqReAjxlcN9AlYDEoye8v2eQp+L9v+PUeDql/wsbaUhSsLR0sjj3PtbBtt+02AN3A==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@2.0.5': + resolution: {integrity: sha512-Sw3rz2m6bBADeQpr3+MD7Ch4E1l15DTt/+dfqKnwkm3cn4BrYwnArmvKeZdVsFRDjMyjlKIP88bw1r7o+9aqzw==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + '@capsizecss/unpack@2.4.0': resolution: {integrity: sha512-GrSU71meACqcmIUxPYOJvGKF0yryjN/L1aCuE9DViCTJI7bfkjgYDPD1zbNDcINJwSSP6UaBZY9GAbYDO7re0Q==} @@ -469,14 +525,25 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@kixelated/hang@0.2.1': - resolution: {integrity: sha512-jTTuuHh/J1bWeYkefLekwrWexkmH3yi0xR6leamPUxbzsy+bNBFsubpOkjndnIzuW/nS4/Vq6HrbczZlBStr7w==} + '@kixelated/hang@0.2.5': + resolution: {integrity: sha512-Uw7qFrJ34zvX/cVh97TtHFhY1nxdDEqBp+ckG6t+V+BmSg0AgwUOWPFISl1uDjkCsR84IkFw+zN3HSt4bYvXgw==} + peerDependencies: + solid-js: ^1.9.7 - '@kixelated/moq@0.6.0': - resolution: {integrity: sha512-etaHsvQX/LH8p34xCF865B3ad3i1hvhBxQloXYI/wjyUYawz1CgTyoqOEwIVp2XgiuJrimZR/500I5xFaFQO6w==} + '@kixelated/moq@0.6.1': + resolution: {integrity: sha512-fdEbFghz0NwrDYmjntDVvYYAvIFpgtxrY5MzM7uexFimyEtMCfIt9Th4bcL54vpZm6l5R6gsL1IEBUHo4AdOfg==} - '@kixelated/signals@0.2.0': - resolution: {integrity: sha512-9mEmWGuvfcv8L2GhrW3t3zg2GDWv3QbYd0gX5IK7DW3BK5xGy8f+ftyGHLGyTl8pRHPyaZh9eOQi64kDGBawKw==} + '@kixelated/signals@0.3.0': + resolution: {integrity: sha512-oLBrY27OKyyB5d4++HE2GGyR5siIlWWc8ZHNcGyKKk+kMY2AEAwpJnA8IvyUaJkfQvc6VMTYXRSDS7YON14QRQ==} + peerDependencies: + '@types/react': ^19.1.8 + react: ^19.0.0 + solid-js: ^1.9.7 + peerDependenciesMeta: + react: + optional: true + solid-js: + optional: true '@mdx-js/mdx@3.1.0': resolution: {integrity: sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==} @@ -685,6 +752,9 @@ packages: '@types/node@22.15.29': resolution: {integrity: sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ==} + '@types/react@19.1.8': + resolution: {integrity: sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==} + '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} @@ -1414,9 +1484,6 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -2423,6 +2490,9 @@ packages: zod@3.25.51: resolution: {integrity: sha512-TQSnBldh+XSGL+opiSIq0575wvDPqu09AqWe1F7JhUMKY+M91/aGlK4MhpVNO7MgYfHcVCB1ffwAUTJzllKJqg==} + zod@3.25.67: + resolution: {integrity: sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==} + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -2648,6 +2718,41 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@biomejs/biome@2.0.5': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 2.0.5 + '@biomejs/cli-darwin-x64': 2.0.5 + '@biomejs/cli-linux-arm64': 2.0.5 + '@biomejs/cli-linux-arm64-musl': 2.0.5 + '@biomejs/cli-linux-x64': 2.0.5 + '@biomejs/cli-linux-x64-musl': 2.0.5 + '@biomejs/cli-win32-arm64': 2.0.5 + '@biomejs/cli-win32-x64': 2.0.5 + + '@biomejs/cli-darwin-arm64@2.0.5': + optional: true + + '@biomejs/cli-darwin-x64@2.0.5': + optional: true + + '@biomejs/cli-linux-arm64-musl@2.0.5': + optional: true + + '@biomejs/cli-linux-arm64@2.0.5': + optional: true + + '@biomejs/cli-linux-x64-musl@2.0.5': + optional: true + + '@biomejs/cli-linux-x64@2.0.5': + optional: true + + '@biomejs/cli-win32-arm64@2.0.5': + optional: true + + '@biomejs/cli-win32-x64@2.0.5': + optional: true + '@capsizecss/unpack@2.4.0': dependencies: blob-to-buffer: 1.2.9 @@ -2837,21 +2942,26 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - '@kixelated/hang@0.2.1': + '@kixelated/hang@0.2.5(@types/react@19.1.8)(solid-js@1.9.7)': dependencies: - '@kixelated/moq': 0.6.0 - '@kixelated/signals': 0.2.0 + '@kixelated/moq': 0.6.1 + '@kixelated/signals': 0.3.0(@types/react@19.1.8)(solid-js@1.9.7) buffer: 6.0.3 - lodash: 4.17.21 solid-js: 1.9.7 - zod: 3.25.51 + zod: 3.25.67 + transitivePeerDependencies: + - '@types/react' + - react - '@kixelated/moq@0.6.0': + '@kixelated/moq@0.6.1': dependencies: buffer: 6.0.3 - '@kixelated/signals@0.2.0': + '@kixelated/signals@0.3.0(@types/react@19.1.8)(solid-js@1.9.7)': dependencies: + '@types/react': 19.1.8 + dequal: 2.0.3 + optionalDependencies: solid-js: 1.9.7 '@mdx-js/mdx@3.1.0(acorn@8.14.1)': @@ -3074,6 +3184,10 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/react@19.1.8': + dependencies: + csstype: 3.1.3 + '@types/unist@2.0.11': {} '@types/unist@3.0.3': {} @@ -3959,8 +4073,6 @@ snapshots: lodash.merge@4.6.2: {} - lodash@4.17.21: {} - longest-streak@3.1.0: {} lru-cache@10.4.3: {} @@ -5288,4 +5400,6 @@ snapshots: zod@3.25.51: {} + zod@3.25.67: {} + zwitch@2.0.4: {} diff --git a/src/components/fail.tsx b/src/components/fail.tsx index ce36b5e..a9bf688 100644 --- a/src/components/fail.tsx +++ b/src/components/fail.tsx @@ -1,4 +1,4 @@ -import { Show, createEffect } from "solid-js"; +import { createEffect, Show } from "solid-js"; export default function Fail(props: { error?: Error }) { createEffect(() => { diff --git a/src/components/publish.tsx b/src/components/publish.tsx index af5e82b..295bab6 100644 --- a/src/components/publish.tsx +++ b/src/components/publish.tsx @@ -1,7 +1,7 @@ -import { Connection, Publish, Support } from "@kixelated/hang"; import { adjectives, animals, uniqueNamesGenerator } from "unique-names-generator"; -import { Show, createEffect, onCleanup } from "solid-js"; +import "@kixelated/hang/support/element"; +import "@kixelated/hang/publish/element"; export default function () { const name = uniqueNamesGenerator({ dictionaries: [adjectives, animals], separator: "-" }); @@ -9,43 +9,9 @@ export default function () { `${import.meta.env.PUBLIC_RELAY_SCHEME}://${import.meta.env.PUBLIC_RELAY_HOST}/anon/${name}.hang`, ); - const preview = ( -