@pikku/bun-server 0.12.11 → 0.12.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/dist/pikku-bun-server.d.ts +4 -0
- package/dist/pikku-bun-server.js +11 -4
- package/dist/pikku-bun-server.js.map +1 -1
- package/package.json +12 -8
- package/run-tests.sh +35 -21
- package/src/bun-event-hub-service.test.ts +0 -77
- package/src/bun-event-hub-service.ts +0 -54
- package/src/index.ts +0 -2
- package/src/local-content.test.ts +0 -193
- package/src/pikku-bun-server.test.ts +0 -62
- package/src/pikku-bun-server.ts +0 -484
- package/src/static-mount.test.ts +0 -330
- package/tsconfig.json +0 -18
- package/tsconfig.tsbuildinfo +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# @pikku/bun-server
|
|
2
2
|
|
|
3
|
+
## 0.12.12
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- dfd7019: An MCP call that needs a session is refused with an OAuth challenge
|
|
8
|
+
|
|
9
|
+
A tool fronting a session-requiring function used to answer an unauthenticated
|
|
10
|
+
caller with `200` and `isError: true`, which a client reads as a tool that
|
|
11
|
+
broke rather than one it has not authenticated for — so OAuth discovery never
|
|
12
|
+
began. Such a call now gets `401` with a `WWW-Authenticate: Bearer` challenge
|
|
13
|
+
naming the resource metadata, and `/.well-known/oauth-protected-resource` is
|
|
14
|
+
served alongside the MCP endpoint.
|
|
15
|
+
|
|
16
|
+
The endpoint is not gated as a whole. `mcpTargetRequiresSession` reads the
|
|
17
|
+
declarations the runner already enforces — a `pikkuFunc` needs a session, a
|
|
18
|
+
`pikkuSessionlessFunc` needs one only where it says `auth: true` — so public
|
|
19
|
+
and private tools can share one server and only the private ones are
|
|
20
|
+
challenged.
|
|
21
|
+
|
|
22
|
+
`createFetchHandler` and `createHTTPRequestHandler` take an optional `auth`
|
|
23
|
+
describing what to advertise (`authorizationServers`, `scopesSupported`,
|
|
24
|
+
`resourceName`), surfaced on both servers as an `mcpAuth` option. Every field
|
|
25
|
+
defaults from the request, because a pikku app is usually its own
|
|
26
|
+
authorization server. Both handlers now also return `ownsPath`, because the
|
|
27
|
+
discovery document lives outside `mcpPath` and a host routing on the endpoint
|
|
28
|
+
alone would 404 the document its own challenge points at.
|
|
29
|
+
|
|
30
|
+
- Updated dependencies [c842054]
|
|
31
|
+
- Updated dependencies [dfd7019]
|
|
32
|
+
- Updated dependencies [dfd7019]
|
|
33
|
+
- Updated dependencies [dfd7019]
|
|
34
|
+
- Updated dependencies [dfd7019]
|
|
35
|
+
- Updated dependencies [9b978e7]
|
|
36
|
+
- Updated dependencies [1469e73]
|
|
37
|
+
- @pikku/core@0.12.113
|
|
38
|
+
- @pikku/modelcontextprotocol@0.12.12
|
|
39
|
+
|
|
3
40
|
## 0.12.11
|
|
4
41
|
|
|
5
42
|
### Patch Changes
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { MCPAuthOptions } from '@pikku/modelcontextprotocol';
|
|
1
2
|
import type { CoreConfig } from '@pikku/core/types';
|
|
2
3
|
import type { JWTService, Logger } from '@pikku/core/services';
|
|
3
4
|
import type { LocalContentConfig } from '@pikku/core/services/local-content';
|
|
@@ -24,6 +25,7 @@ export type PikkuBunServerOptions = RunHTTPWiringOptions & {
|
|
|
24
25
|
prompts?: unknown[];
|
|
25
26
|
};
|
|
26
27
|
mcpPath?: string;
|
|
28
|
+
mcpAuth?: MCPAuthOptions;
|
|
27
29
|
contentSigningJWT?: JWTService;
|
|
28
30
|
};
|
|
29
31
|
export type ShutdownHooks = {
|
|
@@ -38,6 +40,8 @@ export declare class PikkuBunServer {
|
|
|
38
40
|
private readonly options;
|
|
39
41
|
private readonly mcpJson?;
|
|
40
42
|
private readonly mcpPath;
|
|
43
|
+
private readonly mcpAuth?;
|
|
44
|
+
private mcpOwnsPath?;
|
|
41
45
|
private mcpHandler?;
|
|
42
46
|
private readonly localContent?;
|
|
43
47
|
constructor(config: BunServerConfig, logger: Logger, options?: PikkuBunServerOptions);
|
package/dist/pikku-bun-server.js
CHANGED
|
@@ -26,15 +26,18 @@ export class PikkuBunServer {
|
|
|
26
26
|
options;
|
|
27
27
|
mcpJson;
|
|
28
28
|
mcpPath;
|
|
29
|
+
mcpAuth;
|
|
30
|
+
mcpOwnsPath;
|
|
29
31
|
mcpHandler;
|
|
30
32
|
localContent;
|
|
31
33
|
constructor(config, logger, options = {}) {
|
|
32
34
|
this.config = config;
|
|
33
35
|
this.logger = logger;
|
|
34
|
-
const { eventHub, mcpJson, mcpPath, contentSigningJWT, ...httpOptions } = options;
|
|
36
|
+
const { eventHub, mcpJson, mcpPath, mcpAuth, contentSigningJWT, ...httpOptions } = options;
|
|
35
37
|
this.eventHub = eventHub ?? new BunEventHubService();
|
|
36
38
|
this.mcpJson = mcpJson;
|
|
37
39
|
this.mcpPath = mcpPath ?? '/mcp';
|
|
40
|
+
this.mcpAuth = mcpAuth;
|
|
38
41
|
this.options = httpOptions;
|
|
39
42
|
this.localContent = config.content
|
|
40
43
|
? createLocalContentRequestHandler({
|
|
@@ -71,8 +74,12 @@ export class PikkuBunServer {
|
|
|
71
74
|
},
|
|
72
75
|
}, this.logger);
|
|
73
76
|
await mcpServer.init();
|
|
74
|
-
const { handler } = mcpServer.createFetchHandler({
|
|
77
|
+
const { handler, ownsPath } = mcpServer.createFetchHandler({
|
|
78
|
+
path: this.mcpPath,
|
|
79
|
+
auth: this.mcpAuth,
|
|
80
|
+
});
|
|
75
81
|
this.mcpHandler = handler;
|
|
82
|
+
this.mcpOwnsPath = ownsPath;
|
|
76
83
|
this.logger.info(`pikku-bun-server: MCP mounted at ${this.mcpPath}`);
|
|
77
84
|
}
|
|
78
85
|
catch (err) {
|
|
@@ -80,7 +87,7 @@ export class PikkuBunServer {
|
|
|
80
87
|
}
|
|
81
88
|
}
|
|
82
89
|
async start() {
|
|
83
|
-
const { config, logger, options, eventHub, mcpHandler
|
|
90
|
+
const { config, logger, options, eventHub, mcpHandler } = this;
|
|
84
91
|
this.server = Bun.serve({
|
|
85
92
|
port: config.port,
|
|
86
93
|
hostname: config.hostname,
|
|
@@ -110,7 +117,7 @@ export class PikkuBunServer {
|
|
|
110
117
|
}
|
|
111
118
|
if (mcpHandler) {
|
|
112
119
|
const pathname = new URL(req.url).pathname;
|
|
113
|
-
if (
|
|
120
|
+
if (this.mcpOwnsPath?.(pathname)) {
|
|
114
121
|
return await mcpHandler(req);
|
|
115
122
|
}
|
|
116
123
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pikku-bun-server.js","sourceRoot":"","sources":["../src/pikku-bun-server.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pikku-bun-server.js","sourceRoot":"","sources":["../src/pikku-bun-server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikku/bun-server",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.12",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/pikkujs/pikku.git",
|
|
7
|
+
"directory": "packages/runtimes/bun-server"
|
|
8
|
+
},
|
|
4
9
|
"description": "Pikku server adapter for Bun (Bun.serve)",
|
|
5
10
|
"license": "MIT",
|
|
6
11
|
"author": "yasser.fadl@gmail.com",
|
|
@@ -16,8 +21,8 @@
|
|
|
16
21
|
"prepublishOnly": "bun run build"
|
|
17
22
|
},
|
|
18
23
|
"peerDependencies": {
|
|
19
|
-
"@pikku/core": "^0.12.
|
|
20
|
-
"@pikku/modelcontextprotocol": "^0.12.
|
|
24
|
+
"@pikku/core": "^0.12.113",
|
|
25
|
+
"@pikku/modelcontextprotocol": "^0.12.12"
|
|
21
26
|
},
|
|
22
27
|
"peerDependenciesMeta": {
|
|
23
28
|
"@pikku/modelcontextprotocol": {
|
|
@@ -25,12 +30,11 @@
|
|
|
25
30
|
}
|
|
26
31
|
},
|
|
27
32
|
"devDependencies": {
|
|
28
|
-
"@pikku/core": "^0.12.
|
|
29
|
-
"@pikku/modelcontextprotocol": "^0.12.
|
|
30
|
-
"@types/bun": "^1.4.0"
|
|
31
|
-
"typescript": "^6.0.3"
|
|
33
|
+
"@pikku/core": "^0.12.113",
|
|
34
|
+
"@pikku/modelcontextprotocol": "^0.12.12",
|
|
35
|
+
"@types/bun": "^1.4.0"
|
|
32
36
|
},
|
|
33
37
|
"engines": {
|
|
34
38
|
"bun": ">=1.4.0"
|
|
35
39
|
}
|
|
36
|
-
}
|
|
40
|
+
}
|
package/run-tests.sh
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
|
|
3
|
+
# Enable nullglob to handle cases where no files match the pattern
|
|
3
4
|
shopt -s nullglob
|
|
4
5
|
|
|
6
|
+
# Initialize variables for options
|
|
5
7
|
watch_mode=false
|
|
6
8
|
coverage_mode=false
|
|
7
9
|
|
|
10
|
+
# Parse command-line options
|
|
8
11
|
while [[ $# -gt 0 ]]; do
|
|
9
12
|
case $1 in
|
|
10
13
|
--watch)
|
|
@@ -22,33 +25,44 @@ while [[ $# -gt 0 ]]; do
|
|
|
22
25
|
esac
|
|
23
26
|
done
|
|
24
27
|
|
|
25
|
-
files
|
|
26
|
-
|
|
27
|
-
files+=("$file")
|
|
28
|
-
done < <(find src -type f -name "*.test.ts" -print0)
|
|
28
|
+
# Define the pattern to match your test files
|
|
29
|
+
pattern="src/*.test.ts"
|
|
29
30
|
|
|
31
|
+
# Expand the pattern into an array of files
|
|
32
|
+
files=($(find src -type f -name "*.test.ts"))
|
|
33
|
+
|
|
34
|
+
# Check if any files matched the pattern
|
|
30
35
|
if [ ${#files[@]} -eq 0 ]; then
|
|
31
|
-
echo "No test files found"
|
|
36
|
+
echo "No test files found matching pattern: $pattern"
|
|
37
|
+
if [ "${STRICT_TEST_DISCOVERY}" = "1" ]; then
|
|
38
|
+
exit 1
|
|
39
|
+
fi
|
|
32
40
|
exit 0
|
|
33
41
|
fi
|
|
34
42
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
rm -rf coverage
|
|
45
|
-
exit $status
|
|
46
|
-
fi
|
|
47
|
-
|
|
48
|
-
bun_cmd="bun test"
|
|
43
|
+
# Construct the bun command
|
|
44
|
+
#
|
|
45
|
+
# --parallel gives every test file its own worker process, which is what node's
|
|
46
|
+
# `--test` did. Several suites keep module-level caches (a TypeScript program, a
|
|
47
|
+
# temp fixture directory) that a shared process would leak between files.
|
|
48
|
+
#
|
|
49
|
+
# --timeout because bun caps a test at 5s by default where node had no cap, and
|
|
50
|
+
# the suites that build real TypeScript programs run well past that.
|
|
51
|
+
bun_cmd=(bun test --parallel --timeout 120000)
|
|
49
52
|
|
|
53
|
+
# Append options based on flags
|
|
50
54
|
if [ "$watch_mode" = true ]; then
|
|
51
|
-
|
|
55
|
+
# --watch reruns in one process; parallel workers have nothing to watch.
|
|
56
|
+
bun_cmd=(bun test --watch --timeout 120000)
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
if [ "$coverage_mode" = true ]; then
|
|
60
|
+
# --coverage-dir=. keeps lcov.info at the package root: CI merges every
|
|
61
|
+
# package's report by prefixing its SF paths with the file's own directory,
|
|
62
|
+
# so a nested coverage/ directory would re-root them one level too deep.
|
|
63
|
+
bun_cmd+=(--coverage --coverage-reporter=lcov --coverage-reporter=text --coverage-dir=.)
|
|
64
|
+
export PIKKU_TEST_COVERAGE=1
|
|
52
65
|
fi
|
|
53
66
|
|
|
54
|
-
|
|
67
|
+
# Execute the bun command with the expanded list of files
|
|
68
|
+
"${bun_cmd[@]}" "${files[@]}"
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { describe, test } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
import { BunEventHubService } from './bun-event-hub-service.js'
|
|
4
|
-
|
|
5
|
-
type FakeSocket = {
|
|
6
|
-
subscribe: (topic: string) => void
|
|
7
|
-
unsubscribe: (topic: string) => void
|
|
8
|
-
subscribed: string[]
|
|
9
|
-
unsubscribed: string[]
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const makeSocket = (): FakeSocket => {
|
|
13
|
-
const socket: FakeSocket = {
|
|
14
|
-
subscribed: [],
|
|
15
|
-
unsubscribed: [],
|
|
16
|
-
subscribe: (topic) => socket.subscribed.push(topic),
|
|
17
|
-
unsubscribe: (topic) => socket.unsubscribed.push(topic),
|
|
18
|
-
}
|
|
19
|
-
return socket
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
describe('BunEventHubService', () => {
|
|
23
|
-
test('subscribe/unsubscribe proxy to the registered socket', async () => {
|
|
24
|
-
const hub = new BunEventHubService()
|
|
25
|
-
const socket = makeSocket()
|
|
26
|
-
await hub.onChannelOpened('c1', socket as any)
|
|
27
|
-
|
|
28
|
-
await hub.subscribe('news', 'c1')
|
|
29
|
-
await hub.unsubscribe('news', 'c1')
|
|
30
|
-
|
|
31
|
-
assert.deepEqual(socket.subscribed, ['news'])
|
|
32
|
-
assert.deepEqual(socket.unsubscribed, ['news'])
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
test('subscribe is a no-op for unknown channels', async () => {
|
|
36
|
-
const hub = new BunEventHubService()
|
|
37
|
-
await assert.doesNotReject(hub.subscribe('news', 'missing'))
|
|
38
|
-
await assert.doesNotReject(hub.unsubscribe('news', 'missing'))
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
test('publish does nothing before a server is set', async () => {
|
|
42
|
-
const hub = new BunEventHubService()
|
|
43
|
-
await assert.doesNotReject(hub.publish('news', null, { a: 1 }))
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
test('publish serializes JSON messages and forwards binary as-is', async () => {
|
|
47
|
-
const hub = new BunEventHubService()
|
|
48
|
-
const calls: Array<[string, unknown, boolean]> = []
|
|
49
|
-
hub.setServer({
|
|
50
|
-
publish: (topic: string, data: unknown, binary: boolean) =>
|
|
51
|
-
calls.push([topic, data, binary]),
|
|
52
|
-
} as any)
|
|
53
|
-
|
|
54
|
-
await hub.publish('news', null, { hello: 'world' })
|
|
55
|
-
const bin = new Uint8Array([1, 2, 3])
|
|
56
|
-
await hub.publish('bin', null, bin as any, true)
|
|
57
|
-
|
|
58
|
-
assert.deepEqual(calls[0], [
|
|
59
|
-
'news',
|
|
60
|
-
JSON.stringify({ hello: 'world' }),
|
|
61
|
-
false,
|
|
62
|
-
])
|
|
63
|
-
assert.equal(calls[1][0], 'bin')
|
|
64
|
-
assert.equal(calls[1][1], bin)
|
|
65
|
-
assert.equal(calls[1][2], true)
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
test('onChannelClosed removes the socket so later subscribes are no-ops', async () => {
|
|
69
|
-
const hub = new BunEventHubService()
|
|
70
|
-
const socket = makeSocket()
|
|
71
|
-
await hub.onChannelOpened('c1', socket as any)
|
|
72
|
-
await hub.onChannelClosed('c1')
|
|
73
|
-
|
|
74
|
-
await hub.subscribe('news', 'c1')
|
|
75
|
-
assert.deepEqual(socket.subscribed, [])
|
|
76
|
-
})
|
|
77
|
-
})
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import type { ServerWebSocket, Server } from 'bun'
|
|
2
|
-
|
|
3
|
-
type AnyServer = Server<unknown>
|
|
4
|
-
import type { EventHubService } from '@pikku/core/channel'
|
|
5
|
-
|
|
6
|
-
export class BunEventHubService<
|
|
7
|
-
Mappings extends Record<string, unknown> = {},
|
|
8
|
-
> implements EventHubService<Mappings> {
|
|
9
|
-
private sockets: Map<string, ServerWebSocket<unknown>> = new Map()
|
|
10
|
-
private server: AnyServer | null = null
|
|
11
|
-
|
|
12
|
-
public setServer(server: AnyServer): void {
|
|
13
|
-
this.server = server
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
public async subscribe<T extends keyof Mappings>(
|
|
17
|
-
topic: T,
|
|
18
|
-
channelId: string
|
|
19
|
-
): Promise<void> {
|
|
20
|
-
this.sockets.get(channelId)?.subscribe(topic as string)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
public async unsubscribe<T extends keyof Mappings>(
|
|
24
|
-
topic: T,
|
|
25
|
-
channelId: string
|
|
26
|
-
): Promise<void> {
|
|
27
|
-
this.sockets.get(channelId)?.unsubscribe(topic as string)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
public async publish<T extends keyof Mappings>(
|
|
31
|
-
topic: T,
|
|
32
|
-
channelId: string | null,
|
|
33
|
-
message: Mappings[T],
|
|
34
|
-
isBinary?: boolean
|
|
35
|
-
): Promise<void> {
|
|
36
|
-
if (!this.server) return
|
|
37
|
-
if (isBinary) {
|
|
38
|
-
this.server.publish(topic as string, message as any, true)
|
|
39
|
-
} else {
|
|
40
|
-
this.server.publish(topic as string, JSON.stringify(message), false)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
public async onChannelOpened(
|
|
45
|
-
channelId: string,
|
|
46
|
-
ws: ServerWebSocket<unknown>
|
|
47
|
-
): Promise<void> {
|
|
48
|
-
this.sockets.set(channelId, ws)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
public async onChannelClosed(channelId: string): Promise<void> {
|
|
52
|
-
this.sockets.delete(channelId)
|
|
53
|
-
}
|
|
54
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
import { describe, test, before, after } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
import {
|
|
4
|
-
mkdtempSync,
|
|
5
|
-
mkdirSync,
|
|
6
|
-
writeFileSync,
|
|
7
|
-
readFileSync,
|
|
8
|
-
rmSync,
|
|
9
|
-
} from 'node:fs'
|
|
10
|
-
import { tmpdir } from 'node:os'
|
|
11
|
-
import { join } from 'node:path'
|
|
12
|
-
import { setSingletonServices } from '@pikku/core/state'
|
|
13
|
-
import { resetPikkuState } from '@pikku/core/state'
|
|
14
|
-
import { LocalContent } from '@pikku/core/services/local-content'
|
|
15
|
-
import type { JWTService, Logger } from '@pikku/core/services'
|
|
16
|
-
import { PikkuBunServer } from './pikku-bun-server.js'
|
|
17
|
-
|
|
18
|
-
const noopLogger = {
|
|
19
|
-
info: () => {},
|
|
20
|
-
error: () => {},
|
|
21
|
-
warn: () => {},
|
|
22
|
-
debug: () => {},
|
|
23
|
-
trace: () => {},
|
|
24
|
-
setLevel: () => {},
|
|
25
|
-
} as unknown as Logger
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Signs and verifies with a plain base64 round-trip. The point of these tests is
|
|
29
|
-
* that the server checks the SAME claims the signer wrote, not that any
|
|
30
|
-
* particular algorithm is used — a real JWT here would only slow them down.
|
|
31
|
-
*/
|
|
32
|
-
const fakeJWT = {
|
|
33
|
-
encode: async (_expiry: string, payload: unknown) =>
|
|
34
|
-
Buffer.from(JSON.stringify(payload)).toString('base64url'),
|
|
35
|
-
decode: async (token: string) =>
|
|
36
|
-
JSON.parse(Buffer.from(token, 'base64url').toString()),
|
|
37
|
-
} as unknown as JWTService
|
|
38
|
-
|
|
39
|
-
describe('PikkuBunServer local content', () => {
|
|
40
|
-
let server: PikkuBunServer
|
|
41
|
-
let content: LocalContent
|
|
42
|
-
let tmpDir: string
|
|
43
|
-
let origin: string
|
|
44
|
-
|
|
45
|
-
before(async () => {
|
|
46
|
-
resetPikkuState()
|
|
47
|
-
setSingletonServices({
|
|
48
|
-
logger: noopLogger,
|
|
49
|
-
schema: {
|
|
50
|
-
compileSchema: () => {},
|
|
51
|
-
getSchemaNames: () => new Set<string>(),
|
|
52
|
-
},
|
|
53
|
-
} as any)
|
|
54
|
-
tmpDir = mkdtempSync(join(tmpdir(), 'pikku-bun-content-'))
|
|
55
|
-
mkdirSync(join(tmpDir, 'bucket'), { recursive: true })
|
|
56
|
-
writeFileSync(join(tmpDir, 'bucket', 'existing.bin'), 'already here')
|
|
57
|
-
|
|
58
|
-
const contentConfig = {
|
|
59
|
-
localFileUploadPath: tmpDir,
|
|
60
|
-
uploadUrlPrefix: '/upload',
|
|
61
|
-
assetUrlPrefix: '/assets',
|
|
62
|
-
sizeLimit: '1mb',
|
|
63
|
-
}
|
|
64
|
-
// The service under test on the client side: the URLs it hands out are
|
|
65
|
-
// exactly what the server must answer, so they are not hand-written here.
|
|
66
|
-
content = new LocalContent(contentConfig, noopLogger, fakeJWT)
|
|
67
|
-
|
|
68
|
-
server = new PikkuBunServer(
|
|
69
|
-
{
|
|
70
|
-
port: 0,
|
|
71
|
-
hostname: '127.0.0.1',
|
|
72
|
-
content: contentConfig,
|
|
73
|
-
} as any,
|
|
74
|
-
noopLogger,
|
|
75
|
-
{ contentSigningJWT: fakeJWT }
|
|
76
|
-
)
|
|
77
|
-
await server.init()
|
|
78
|
-
await server.start()
|
|
79
|
-
origin = `http://127.0.0.1:${server.port}`
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
after(async () => {
|
|
83
|
-
await server.stop()
|
|
84
|
-
rmSync(tmpDir, { recursive: true, force: true })
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
test('answers the upload URL the content service hands out', async () => {
|
|
88
|
-
const { uploadUrl } = await content.getUploadURL({
|
|
89
|
-
bucket: 'bucket',
|
|
90
|
-
fileKey: 'nested/file.bin',
|
|
91
|
-
contentType: 'application/octet-stream',
|
|
92
|
-
} as any)
|
|
93
|
-
|
|
94
|
-
const response = await fetch(`${origin}${uploadUrl}`, {
|
|
95
|
-
method: 'PUT',
|
|
96
|
-
body: 'uploaded bytes',
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
assert.equal(response.status, 200)
|
|
100
|
-
assert.equal(
|
|
101
|
-
readFileSync(join(tmpDir, 'bucket', 'nested', 'file.bin'), 'utf8'),
|
|
102
|
-
'uploaded bytes'
|
|
103
|
-
)
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
test('serves an asset through the signed URL the content service produces', async () => {
|
|
107
|
-
const signed = await content.signContentKey({
|
|
108
|
-
bucket: 'bucket',
|
|
109
|
-
contentKey: 'existing.bin',
|
|
110
|
-
dateLessThan: new Date(Date.now() + 60_000),
|
|
111
|
-
} as any)
|
|
112
|
-
|
|
113
|
-
const response = await fetch(`${origin}${signed}`)
|
|
114
|
-
assert.equal(response.status, 200)
|
|
115
|
-
assert.equal(await response.text(), 'already here')
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
test('refuses an unsigned asset read', async () => {
|
|
119
|
-
const response = await fetch(`${origin}/assets/bucket/existing.bin`)
|
|
120
|
-
assert.equal(response.status, 403)
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
test('refuses a signature minted for a different asset', async () => {
|
|
124
|
-
// The signature is valid and unexpired — only the path differs. Without the
|
|
125
|
-
// path claim being checked, one signed URL would read the whole bucket.
|
|
126
|
-
const signed = await content.signContentKey({
|
|
127
|
-
bucket: 'bucket',
|
|
128
|
-
contentKey: 'existing.bin',
|
|
129
|
-
dateLessThan: new Date(Date.now() + 60_000),
|
|
130
|
-
} as any)
|
|
131
|
-
writeFileSync(join(tmpDir, 'bucket', 'other.bin'), 'other')
|
|
132
|
-
|
|
133
|
-
const query = signed.slice(signed.indexOf('?'))
|
|
134
|
-
const response = await fetch(`${origin}/assets/bucket/other.bin${query}`)
|
|
135
|
-
assert.equal(response.status, 403)
|
|
136
|
-
})
|
|
137
|
-
|
|
138
|
-
test('refuses an expired signature', async () => {
|
|
139
|
-
const signed = await content.signContentKey({
|
|
140
|
-
bucket: 'bucket',
|
|
141
|
-
contentKey: 'existing.bin',
|
|
142
|
-
dateLessThan: new Date(Date.now() - 1_000),
|
|
143
|
-
} as any)
|
|
144
|
-
|
|
145
|
-
const response = await fetch(`${origin}${signed}`)
|
|
146
|
-
assert.equal(response.status, 403)
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
// `fetch` normalises `..` out of the path before the request leaves the
|
|
150
|
-
// client, so this cannot drive the guard itself — that is covered directly in
|
|
151
|
-
// core's local-content-request-handler.test.ts. What it does prove is that
|
|
152
|
-
// nothing in the server path un-normalises it back into a write.
|
|
153
|
-
test('does not write outside the content directory', async () => {
|
|
154
|
-
writeFileSync(join(tmpDir, '..', 'pikku-bun-content-secret.txt'), 'secret')
|
|
155
|
-
try {
|
|
156
|
-
const response = await fetch(
|
|
157
|
-
`${origin}/upload/%2e%2e/pikku-bun-content-secret.txt`,
|
|
158
|
-
{ method: 'PUT', body: 'overwritten' }
|
|
159
|
-
)
|
|
160
|
-
assert.notEqual(response.status, 200)
|
|
161
|
-
assert.equal(
|
|
162
|
-
readFileSync(
|
|
163
|
-
join(tmpDir, '..', 'pikku-bun-content-secret.txt'),
|
|
164
|
-
'utf8'
|
|
165
|
-
),
|
|
166
|
-
'secret'
|
|
167
|
-
)
|
|
168
|
-
} finally {
|
|
169
|
-
rmSync(join(tmpDir, '..', 'pikku-bun-content-secret.txt'), {
|
|
170
|
-
force: true,
|
|
171
|
-
})
|
|
172
|
-
}
|
|
173
|
-
})
|
|
174
|
-
|
|
175
|
-
test('rejects an upload over the size limit', async () => {
|
|
176
|
-
const { uploadUrl } = await content.getUploadURL({
|
|
177
|
-
bucket: 'bucket',
|
|
178
|
-
fileKey: 'too-big.bin',
|
|
179
|
-
contentType: 'application/octet-stream',
|
|
180
|
-
} as any)
|
|
181
|
-
|
|
182
|
-
const response = await fetch(`${origin}${uploadUrl}`, {
|
|
183
|
-
method: 'PUT',
|
|
184
|
-
body: Buffer.alloc(1024 * 1024 + 1),
|
|
185
|
-
})
|
|
186
|
-
assert.equal(response.status, 413)
|
|
187
|
-
})
|
|
188
|
-
|
|
189
|
-
test('leaves non-content paths to the router', async () => {
|
|
190
|
-
const response = await fetch(`${origin}/uploadsomething`)
|
|
191
|
-
assert.equal(response.status, 404)
|
|
192
|
-
})
|
|
193
|
-
})
|