Skip to content

Commit 7d22777

Browse files
authored
feat!: deviceId as hex, not z32 (#14)
1 parent ce25b54 commit 7d22777

10 files changed

Lines changed: 20 additions & 41 deletions

File tree

README.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ Content-Type: application/json
264264
265265
{
266266
"mapId": "custom",
267-
"receiverDeviceId": "kmx8sejfn..." // z32-encoded public key
267+
"receiverDeviceId": "a1b2c3d4..." // hex-encoded public key
268268
}
269269
```
270270

@@ -326,7 +326,7 @@ POST /downloads
326326
Content-Type: application/json
327327
328328
{
329-
"senderDeviceId": "z32-encoded-public-key",
329+
"senderDeviceId": "a1b2c3d4e5f6...",
330330
"shareId": "abc123...",
331331
"mapShareUrls": ["http://192.168.1.100:9090/mapShares/abc123..."],
332332
"estimatedSizeBytes": 12345678
@@ -370,7 +370,7 @@ POST /mapShares/{shareId}/decline
370370
Content-Type: application/json
371371
372372
{
373-
"senderDeviceId": "z32-encoded-public-key",
373+
"senderDeviceId": "a1b2c3d4e5f6...",
374374
"mapShareUrls": ["http://192.168.1.100:9090/mapShares/abc123..."],
375375
"reason": "disk_full" | "user_rejected" | "other reason"
376376
}
@@ -385,7 +385,6 @@ Called on the receiver's local server. The server handles making the P2P request
385385
```javascript
386386
import { createServer } from '@comapeo/map-server'
387387
import Hypercore from 'hypercore'
388-
import z32 from 'z32'
389388

390389
const deviceAKeyPair = Hypercore.keyPair()
391390
const serverA = createServer({
@@ -398,7 +397,7 @@ const serverA = createServer({
398397
const { localPort } = await serverA.listen()
399398

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

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

564563
### Generic Errors
565564

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@
7373
"secret-stream-http": "^1.0.1",
7474
"styled-map-package": "^4.0.1",
7575
"typebox": "^1.0.61",
76-
"typed-event-target": "^3.4.0",
77-
"z32": "^1.1.0"
76+
"typed-event-target": "^3.4.0"
7877
},
7978
"bundleDependencies": [
8079
"@whatwg-node/server"

src/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
Agent,
1010
createServer as createSecretStreamServer,
1111
} from 'secret-stream-http'
12-
import z32 from 'z32'
1312

1413
import { Context } from './context.js'
1514
import { fetchAPI } from './lib/fetch-api.js'
@@ -79,7 +78,7 @@ export function createServer(options: ServerOptions) {
7978
serverAdapter(req, res, {
8079
isLocalhost: false,
8180
// @ts-expect-error - the types for this are too hard and making them work would not add any type safety.
82-
remoteDeviceId: z32.encode(req.socket.remotePublicKey),
81+
remoteDeviceId: Buffer.from(req.socket.remotePublicKey).toString('hex'),
8382
})
8483
})
8584
const secretStreamServer = createSecretStreamServer(remoteHttpServer, {

src/lib/download-request.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Agent as SecretStreamAgent } from 'secret-stream-http'
2-
import z32 from 'z32'
32

43
import { TypedEventTarget } from '../lib/event-target.js'
54
import type { DownloadCreateParams } from '../routes/downloads.js'
@@ -46,7 +45,7 @@ export class DownloadRequest extends TypedEventTarget<
4645
}
4746
let remotePublicKey: Uint8Array
4847
try {
49-
remotePublicKey = z32.decode(this.#state.senderDeviceId)
48+
remotePublicKey = Buffer.from(this.#state.senderDeviceId, 'hex')
5049
} catch {
5150
throw new errors.INVALID_SENDER_DEVICE_ID(
5251
`Invalid sender device ID: ${this.#state.senderDeviceId}`,

src/lib/utils.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import crypto from 'node:crypto'
22

33
import { randomBytes } from 'crypto'
44
import type { SMPStyle } from 'styled-map-package'
5-
import z32 from 'z32'
65

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

@@ -33,7 +32,7 @@ export function getErrorCode(maybeError: unknown) {
3332
export function noop() {}
3433

3534
export function generateId() {
36-
return z32.encode(randomBytes(8))
35+
return randomBytes(8).toString('hex')
3736
}
3837

3938
export function getOrInsert<K, V>(map: Map<K, V>, key: K, value: V): V {

src/routes/map-shares.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
} from 'secret-stream-http'
88
import { Type as T, type Static } from 'typebox'
99
import { Compile } from 'typebox/compile'
10-
import z32 from 'z32'
1110

1211
import type { Context } from '../context.js'
1312
import { errors, StatusError } from '../lib/errors.js'
@@ -151,7 +150,7 @@ export function MapSharesRouter(
151150
throw new errors.INVALID_REQUEST()
152151
}
153152
const { senderDeviceId, mapShareUrls, reason } = parsedBody
154-
const remotePublicKey = z32.decode(senderDeviceId)
153+
const remotePublicKey = Buffer.from(senderDeviceId, 'hex')
155154
const keyPair = ctx.getKeyPair()
156155
let response: Response | undefined
157156
// The sharer could have multiple IPs for different network interfaces, and

test/__snapshots__/map-shares.test.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ exports[`Map Shares and Downloads > Map Shares > should create a map share 1`] =
1313
"mapName": "OSM Bright",
1414
"maxzoom": 6,
1515
"minzoom": 0,
16-
"receiverDeviceId": "tkrq8zmwb8a3m9k15csu3q17qmfgqnp9dskbrg9uq1rydpyxp7qy",
16+
"receiverDeviceId": "8a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c",
1717
"status": "pending",
1818
}
1919
`;

test/helpers.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { http, HttpResponse } from 'msw'
88
import { setupServer } from 'msw/node'
99
import { Agent as SecretStreamAgent } from 'secret-stream-http'
1010
import type { TestContext } from 'vitest'
11-
import z32 from 'z32'
1211

1312
import type { ServerOptions } from '../src/index.js'
1413
import { createServer } from '../src/index.js'
@@ -133,7 +132,7 @@ export async function startServers(
133132
remoteBaseUrl: sender.remoteBaseUrl,
134133
remotePort: sender.remotePort,
135134
keyPair: senderKeyPair,
136-
deviceId: z32.encode(senderKeyPair.publicKey),
135+
deviceId: Buffer.from(senderKeyPair.publicKey).toString('hex'),
137136
eventsPath: (id: string) => `/mapShares/${id}/events`,
138137
}
139138

@@ -146,7 +145,7 @@ export async function startServers(
146145
remoteBaseUrl: receiver.remoteBaseUrl,
147146
localPort: receiver.localPort,
148147
keyPair: receiverKeyPair,
149-
deviceId: z32.encode(receiverKeyPair.publicKey),
148+
deviceId: Buffer.from(receiverKeyPair.publicKey).toString('hex'),
150149
customMapPath: receiver.customMapPath,
151150
eventsPath: (id: string) => `/downloads/${id}/events`,
152151
}

test/map-shares.test.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
Agent as SecretStreamAgent,
1414
} from 'secret-stream-http'
1515
import { describe, it, expect } from 'vitest'
16-
import z32 from 'z32'
1716

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

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

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

11031102
// Create a third device with different keys
11041103
const wrongKeyPair = SecretStreamAgent.keyPair()
1105-
const wrongDeviceId = z32.encode(wrongKeyPair.publicKey)
1104+
const wrongDeviceId = Buffer.from(wrongKeyPair.publicKey).toString('hex')
11061105

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

11331132
// Create a third device with different keys
11341133
const wrongKeyPair = SecretStreamAgent.keyPair()
1135-
const wrongDeviceId = z32.encode(wrongKeyPair.publicKey)
1134+
const wrongDeviceId = Buffer.from(wrongKeyPair.publicKey).toString('hex')
11361135

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

11861185
// Create a third device
11871186
const wrongKeyPair = SecretStreamAgent.keyPair()
1188-
const wrongDeviceId = z32.encode(wrongKeyPair.publicKey)
1187+
const wrongDeviceId = Buffer.from(wrongKeyPair.publicKey).toString('hex')
11891188

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

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

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

15151514
const response = await receiver.post('downloads', {
15161515
json: {

types/z32.d.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)