Skip to content

Commit de1a17e

Browse files
committed
Remove secret, improve docs
1 parent 10a76d5 commit de1a17e

File tree

4 files changed

+33
-73
lines changed

4 files changed

+33
-73
lines changed

.env.example

Lines changed: 0 additions & 1 deletion
This file was deleted.

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ FROM base AS build
1313
COPY . .
1414

1515
FROM base
16-
RUN pnpm playwright install --with-deps chromium
1716
COPY --from=prod-deps /app/node_modules /app/node_modules
17+
RUN pnpm playwright install --with-deps chromium
1818
COPY --from=build /app/src/index.js /app/src/index.js
1919
CMD ["pnpm", "start"]

README.md

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,31 @@
1-
# Browser 🖥️
1+
# Docker Browser 🖥️
22

33
[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord)
44
[![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite)
55
[![appwrite.io](https://img.shields.io/badge/appwrite-.io-f02e65?style=flat-square)](https://appwrite.io)
66

7-
Appwrite Browser is simple to use and extend REST API meant to simplify screenshot preview, reports, and analysis.
7+
Docker Browser is simple to use and extend REST API meant to simplify screenshot preview, reports, and analysis.
88

99
## Usage
1010

11-
Add Appwrite Browser to your `docker-compose.yml`.
11+
Add Docker Browser to your `docker-compose.yml`.
1212

1313
```
1414
services:
1515
appwrite-browser:
16-
container_name: appwrite-browser
1716
image: appwrite/browser:0.1.0
18-
networks:
19-
- appwrite
20-
environment:
21-
- APPWRITE_BROWSER_SECRET=secret
2217
```
2318

24-
Start browser alongside rest of your services.
19+
Start Docker Browser alongside rest of your services.
2520

2621
```
2722
docker compose up -d
2823
```
2924

30-
Communicate with Appwrite Browser endpoints.
25+
Communicate with Docker Browser endpoints.
3126

3227
```bash
33-
curl -X GET -H "Authorization: Bearer secret" http://appwrite-browser:3000/screenshot?url=http://google.com/ping
28+
curl -X POST -H 'content-type: application/json' -d '{"url":"http://google.com/ping"}' http://appwrite-browser:3000/v1/screenshots
3429
```
3530

3631
## Development
@@ -43,13 +38,7 @@ To install dependencies, run the following command.
4338
pnpm i
4439
```
4540

46-
Next, duplicate `.env.example` into `.env`, and update the values.
47-
48-
```bash
49-
cp .env.example .env
50-
```
51-
52-
Finally, start the server by running `npm start`, and visit use endpoint `http://localhost:3000` as REST API endpoint. To authorize, provide header `Authorization: Bearer <secret>`.
41+
Next, start the server by running `npm start`, and visit use endpoint `http://localhost:3000` as REST API endpoint.
5342

5443
## Contributing
5544

src/index.js

Lines changed: 25 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,20 @@
11
import { createServer } from "node:http";
2-
import { createError } from "h3";
32
import {
43
createApp,
54
createRouter,
65
defineEventHandler,
7-
getValidatedQuery,
86
toNodeListener,
97
} from "h3";
8+
import { readValidatedBody } from "h3";
109
import lighthouseDesktopConfig from "lighthouse/core/config/lr-desktop-config.js";
1110
import lighthouseMobileConfig from "lighthouse/core/config/lr-mobile-config.js";
1211
import { chromium } from "playwright";
1312
import { playAudit } from "playwright-lighthouse";
1413
import { z } from "zod";
1514

1615
const port = process.env.PORT || 3000;
17-
const signature = process.env.APPWRITE_BROWSER_SECRET;
18-
if (!signature) {
19-
throw new Error("APPWRITE_BROWSER_SECRET environment variable is required");
20-
}
2116

22-
const app = createApp({
23-
onRequest: (event) => {
24-
const auth = event.headerssss.get("Authorization");
25-
if (auth === null)
26-
throw createError({
27-
status: 400,
28-
statusMessage: "Unauthorized",
29-
message: "Missing signature",
30-
});
31-
const [type, token] = auth.split(" ");
32-
if (token === null)
33-
throw createError({
34-
status: 400,
35-
statusMessage: "Unauthorized",
36-
message: "Missing signature",
37-
});
38-
if (type !== "Bearer" || token !== signature)
39-
throw createError({
40-
status: 401,
41-
statusMessage: "Unauthorized",
42-
message: "Invalid signature",
43-
});
44-
},
45-
});
17+
const app = createApp();
4618
const router = createRouter();
4719

4820
console.log("Chromium starting...");
@@ -61,55 +33,55 @@ const defaultContext = {
6133
},
6234
};
6335

64-
const screenshotParams = z.object({
65-
url: z.string().startsWith("/"),
36+
const screenshotSchema = z.object({
37+
url: z.string().url(),
6638
color: z.enum(["light", "dark"]).default("light"),
67-
headers: z.string().optional(), // JSON object
39+
headers: z.record(z.string(), z.any()),
6840
});
69-
router.get(
70-
"/screenshot",
41+
router.post(
42+
"/v1/screenshots",
7143
defineEventHandler(async (event) => {
72-
const query = await getValidatedQuery(event, screenshotParams.parse);
44+
const body = await readValidatedBody(event, screenshotSchema.parse);
7345
const context = await browser.newContext({
7446
...defaultContext,
75-
colorScheme: query.color,
76-
extraHTTPHeaders: JSON.parse(query.headers ?? "{}"),
47+
colorScheme: body.color,
48+
extraHTTPHeaders: body.headers,
7749
});
7850
const page = await context.newPage();
79-
await page.goto(query.url);
51+
await page.goto(body.url);
8052
const screen = await page.screenshot();
8153
await context.close();
8254
return screen;
8355
}),
8456
);
8557

86-
const lighthouseParams = z.object({
58+
const lighthouseSchema = z.object({
8759
url: z.string().url(),
8860
viewport: z.enum(["mobile", "desktop"]).default("mobile"),
89-
html: z.string().default("false"),
90-
json: z.string().default("false"),
91-
csv: z.string().default("false"),
61+
json: z.boolean().default(true),
62+
html: z.boolean().default(false),
63+
csv: z.boolean().default(false),
9264
});
9365
const configs = {
9466
mobile: lighthouseMobileConfig,
9567
desktop: lighthouseDesktopConfig,
9668
};
97-
router.get(
98-
"/lighthouse",
69+
router.post(
70+
"/v1/reports",
9971
defineEventHandler(async (event) => {
100-
const query = await getValidatedQuery(event, lighthouseParams.parse);
72+
const body = await readValidatedBody(event, lighthouseSchema.parse);
10173
const context = await browser.newContext(defaultContext);
10274
const page = await context.newPage();
103-
await page.goto(query.url);
75+
await page.goto(body.url);
10476
const results = await playAudit({
10577
reports: {
10678
formats: {
107-
html: query.html === "true",
108-
json: query.json === "true",
109-
csv: query.csv === "true",
79+
html: body.html,
80+
json: body.json,
81+
csv: body.csv,
11082
},
11183
},
112-
config: configs[query.viewport],
84+
config: configs[body.viewport],
11385
page: page,
11486
port: 9222,
11587
thresholds: {
@@ -125,8 +97,8 @@ router.get(
12597
}),
12698
);
12799

128-
router.use(
129-
"/health",
100+
router.get(
101+
"/v1/health",
130102
defineEventHandler(async () => {
131103
return {
132104
status: browser.isConnected() ? "ok" : "error",

0 commit comments

Comments
 (0)