Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ Content-Type: application/json

{
"mapId": "custom",
"receiverDeviceId": "kmx8sejfn..." // z32-encoded public key
"receiverDeviceId": "a1b2c3d4..." // hex-encoded public key
}
```

Expand Down Expand Up @@ -326,7 +326,7 @@ POST /downloads
Content-Type: application/json

{
"senderDeviceId": "z32-encoded-public-key",
"senderDeviceId": "a1b2c3d4e5f6...",
"shareId": "abc123...",
"mapShareUrls": ["http://192.168.1.100:9090/mapShares/abc123..."],
"estimatedSizeBytes": 12345678
Expand Down Expand Up @@ -370,7 +370,7 @@ POST /mapShares/{shareId}/decline
Content-Type: application/json

{
"senderDeviceId": "z32-encoded-public-key",
"senderDeviceId": "a1b2c3d4e5f6...",
"mapShareUrls": ["http://192.168.1.100:9090/mapShares/abc123..."],
"reason": "disk_full" | "user_rejected" | "other reason"
}
Expand All @@ -385,7 +385,6 @@ Called on the receiver's local server. The server handles making the P2P request
```javascript
import { createServer } from '@comapeo/map-server'
import Hypercore from 'hypercore'
import z32 from 'z32'

const deviceAKeyPair = Hypercore.keyPair()
const serverA = createServer({
Expand All @@ -398,7 +397,7 @@ const serverA = createServer({
const { localPort } = await serverA.listen()

// Device B's public key (exchanged via your discovery mechanism)
const deviceBId = 'kmx8sejfn...' // z32-encoded
const deviceBId = 'a1b2c3d4e5f6...' // hex-encoded

// Create share
const res = await fetch(`http://127.0.0.1:${localPort}/mapShares`, {
Expand Down Expand Up @@ -559,7 +558,7 @@ All error responses follow this format:
| `DOWNLOAD_SHARE_DECLINED` | 409 | Cannot download a share that was declined |
| `DOWNLOAD_SHARE_NOT_PENDING` | 409 | Cannot download a share that is not pending |
| `ABORT_NOT_DOWNLOADING` | 409 | Cannot abort a download that is not in progress |
| `INVALID_SENDER_DEVICE_ID` | 400 | The sender device ID is not a valid z32-encoded public key |
| `INVALID_SENDER_DEVICE_ID` | 400 | The sender device ID is not a valid hex-encoded public key |

### Generic Errors

Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@
"secret-stream-http": "^1.0.1",
"styled-map-package": "^4.0.1",
"typebox": "^1.0.61",
"typed-event-target": "^3.4.0",
"z32": "^1.1.0"
"typed-event-target": "^3.4.0"
},
"bundleDependencies": [
"@whatwg-node/server"
Expand Down
3 changes: 1 addition & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
Agent,
createServer as createSecretStreamServer,
} from 'secret-stream-http'
import z32 from 'z32'

import { Context } from './context.js'
import { fetchAPI } from './lib/fetch-api.js'
Expand Down Expand Up @@ -79,7 +78,7 @@ export function createServer(options: ServerOptions) {
serverAdapter(req, res, {
isLocalhost: false,
// @ts-expect-error - the types for this are too hard and making them work would not add any type safety.
remoteDeviceId: z32.encode(req.socket.remotePublicKey),
remoteDeviceId: Buffer.from(req.socket.remotePublicKey).toString('hex'),
})
})
const secretStreamServer = createSecretStreamServer(remoteHttpServer, {
Expand Down
3 changes: 1 addition & 2 deletions src/lib/download-request.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Agent as SecretStreamAgent } from 'secret-stream-http'
import z32 from 'z32'

import { TypedEventTarget } from '../lib/event-target.js'
import type { DownloadCreateParams } from '../routes/downloads.js'
Expand Down Expand Up @@ -46,7 +45,7 @@ export class DownloadRequest extends TypedEventTarget<
}
let remotePublicKey: Uint8Array
try {
remotePublicKey = z32.decode(this.#state.senderDeviceId)
remotePublicKey = Buffer.from(this.#state.senderDeviceId, 'hex')
} catch {
throw new errors.INVALID_SENDER_DEVICE_ID(
`Invalid sender device ID: ${this.#state.senderDeviceId}`,
Expand Down
3 changes: 1 addition & 2 deletions src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import crypto from 'node:crypto'

import { randomBytes } from 'crypto'
import type { SMPStyle } from 'styled-map-package'
import z32 from 'z32'

import type { BBox } from '../types.js'

Expand Down Expand Up @@ -33,7 +32,7 @@ export function getErrorCode(maybeError: unknown) {
export function noop() {}

export function generateId() {
return z32.encode(randomBytes(8))
return randomBytes(8).toString('hex')
}

export function getOrInsert<K, V>(map: Map<K, V>, key: K, value: V): V {
Expand Down
3 changes: 1 addition & 2 deletions src/routes/map-shares.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
} from 'secret-stream-http'
import { Type as T, type Static } from 'typebox'
import { Compile } from 'typebox/compile'
import z32 from 'z32'

import type { Context } from '../context.js'
import { errors, StatusError } from '../lib/errors.js'
Expand Down Expand Up @@ -151,7 +150,7 @@ export function MapSharesRouter(
throw new errors.INVALID_REQUEST()
}
const { senderDeviceId, mapShareUrls, reason } = parsedBody
const remotePublicKey = z32.decode(senderDeviceId)
const remotePublicKey = Buffer.from(senderDeviceId, 'hex')
const keyPair = ctx.getKeyPair()
let response: Response | undefined
// The sharer could have multiple IPs for different network interfaces, and
Expand Down
2 changes: 1 addition & 1 deletion test/__snapshots__/map-shares.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ exports[`Map Shares and Downloads > Map Shares > should create a map share 1`] =
"mapName": "OSM Bright",
"maxzoom": 6,
"minzoom": 0,
"receiverDeviceId": "tkrq8zmwb8a3m9k15csu3q17qmfgqnp9dskbrg9uq1rydpyxp7qy",
"receiverDeviceId": "8a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c",
"status": "pending",
}
`;
5 changes: 2 additions & 3 deletions test/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'
import { Agent as SecretStreamAgent } from 'secret-stream-http'
import type { TestContext } from 'vitest'
import z32 from 'z32'

import type { ServerOptions } from '../src/index.js'
import { createServer } from '../src/index.js'
Expand Down Expand Up @@ -133,7 +132,7 @@ export async function startServers(
remoteBaseUrl: sender.remoteBaseUrl,
remotePort: sender.remotePort,
keyPair: senderKeyPair,
deviceId: z32.encode(senderKeyPair.publicKey),
deviceId: Buffer.from(senderKeyPair.publicKey).toString('hex'),
eventsPath: (id: string) => `/mapShares/${id}/events`,
}

Expand All @@ -146,7 +145,7 @@ export async function startServers(
remoteBaseUrl: receiver.remoteBaseUrl,
localPort: receiver.localPort,
keyPair: receiverKeyPair,
deviceId: z32.encode(receiverKeyPair.publicKey),
deviceId: Buffer.from(receiverKeyPair.publicKey).toString('hex'),
customMapPath: receiver.customMapPath,
eventsPath: (id: string) => `/downloads/${id}/events`,
}
Expand Down
15 changes: 7 additions & 8 deletions test/map-shares.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
Agent as SecretStreamAgent,
} from 'secret-stream-http'
import { describe, it, expect } from 'vitest'
import z32 from 'z32'

import type { MapShareState } from '../src/types.js'
import {
Expand Down Expand Up @@ -151,7 +150,7 @@ describe('Map Shares and Downloads', () => {

// Create a third device (another receiver)
const receiver2KeyPair = SecretStreamAgent.keyPair(Buffer.alloc(32, 2))
const receiver2DeviceId = z32.encode(receiver2KeyPair.publicKey)
const receiver2DeviceId = Buffer.from(receiver2KeyPair.publicKey).toString('hex')

// Create share for first receiver
const share1 = await createShare().json()
Expand Down Expand Up @@ -1102,7 +1101,7 @@ describe('Map Shares and Downloads', () => {

// Create a third device with different keys
const wrongKeyPair = SecretStreamAgent.keyPair()
const wrongDeviceId = z32.encode(wrongKeyPair.publicKey)
const wrongDeviceId = Buffer.from(wrongKeyPair.publicKey).toString('hex')

// Create a share for a different device
const { shareId: shareId2 } = await sender
Expand Down Expand Up @@ -1132,7 +1131,7 @@ describe('Map Shares and Downloads', () => {

// Create a third device with different keys
const wrongKeyPair = SecretStreamAgent.keyPair()
const wrongDeviceId = z32.encode(wrongKeyPair.publicKey)
const wrongDeviceId = Buffer.from(wrongKeyPair.publicKey).toString('hex')

// Create a share for wrongDeviceId
const { shareId } = await sender
Expand Down Expand Up @@ -1185,7 +1184,7 @@ describe('Map Shares and Downloads', () => {

// Create a third device
const wrongKeyPair = SecretStreamAgent.keyPair()
const wrongDeviceId = z32.encode(wrongKeyPair.publicKey)
const wrongDeviceId = Buffer.from(wrongKeyPair.publicKey).toString('hex')

// Create a share for wrongDeviceId
const { shareId } = await sender
Expand Down Expand Up @@ -1494,7 +1493,7 @@ describe('Map Shares and Downloads', () => {

const response = await receiver.post('downloads', {
json: {
senderDeviceId: 'not-a-valid-z32-encoded-public-key',
senderDeviceId: 'not-a-valid-hex-encoded-public-key',
shareId: 'test-share',
mapShareUrls: ['http://127.0.0.1:1/mapShares/test-share'],
estimatedSizeBytes: 1000,
Expand All @@ -1509,8 +1508,8 @@ describe('Map Shares and Downloads', () => {
it('should reject download with sender device ID of wrong length', async (t) => {
const { receiver } = await startServers(t)

// Valid z32 encoding but only 16 bytes instead of 32
const shortKey = z32.encode(new Uint8Array(16))
// Valid hex encoding but only 16 bytes instead of 32
const shortKey = Buffer.from(new Uint8Array(16)).toString('hex')

const response = await receiver.post('downloads', {
json: {
Expand Down
13 changes: 0 additions & 13 deletions types/z32.d.ts

This file was deleted.