Avatar

mmcc

3 public vals
Joined May 19, 2023

Val Town Basic Auth Middleware for Hono

pomdtr/basicAuth but for Hono.

Usage

Register the middleware and you're good to go.

import { basicAuth } from "https://esm.town/v/mmcc/honoBasicAuth";

app.use('/authed/*', basicAuth());

app.get('/auth/profile', c => { });

To authenticate, paste an api token in the password prompt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
function extractToken(authorization) {
const parts = authorization.split(" ");
if (parts[0] == "Bearer") {
return parts[1];
}
if (parts[0] != "Basic") {
return "";
}
const plainAuth = atob(parts[1]);
const credentials = plainAuth.split(":");
// allow `curl <token>@xxx.web.val.run`
return credentials[1] || credentials[0];
}
type User = {
id: string;
};
async function fetchUser(token: string): Promise<User> {
const resp = await fetch("https://api.val.town/v1/me", {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (resp.status !== 200) {
throw new Error("Could not fetch user");
}
return resp.json();
}
async function isTokenValid(token) {
try {
const [visitor, owner] = await Promise.all([fetchUser(token), fetchUser(Deno.env.get("valtown"))]);
return visitor.id == owner.id;
} catch (err) {
return false;
}
}
async function isRequestAuthenticated(req) {
if (!req.headers.has("authorization")) {
return false;
}
const token = extractToken(req.headers.get("authorization"));
return isTokenValid(token);
}
export function basicAuth() {
return async (c, next) => {
if (c.req.headers.get("referer") == "https://www.val.town/") {
return c.html(
`Basic Auth is disabled in Val Town iframes.
<a href="/" target="blank_">Open in a new tab.</a>`,
400,
{
"Content-type": "text/html",
},
);
}
const isAuth = await isRequestAuthenticated(c.req);
if (!isAuth) {
return c.text("Unauthorized", 401, {
"WWW-Authenticate": "Basic",
});
}
await next();
};
}

A val that you can set up as your webhook endpoint for Mux.com to use CLIP for moderation. This is attempting to use the storyboard image, but so far the results seem pretty subpar.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { addVideo } from "https://esm.town/v/mmcc/muxVideoStorage";
import { email } from "https://esm.town/v/std/email";
import process from "node:process";
import Replicate from "npm:replicate";
const replicate = new Replicate({
auth: process.env.REPLICATE_API_TOKEN,
});
const model = "cjwbw/clip-vit-large-patch14:566ab1f111e526640c5154e712d4d54961414278f89d36590f1425badc763ecb";
// since we're going to try running these prompts on storyboard, we're going
// to preface each prompt with details on being a collection of images.
const storyboardPreface = "a collection of images that include";
const classes = [
["safe", "appropriate content"],
["artistic_nudity", "artistic nudity"],
["pornography", "pornographic imagery"],
["nsfw", "NSFW content"],
["hateful", "hateful symbols"],
];
const prompts = classes.map(c => `${storyboardPreface} ${c[1]}`);
export default async function(req: Request): Promise<Response> {
if (req.method === "GET") {
return Response.json({ nada: true });
}
const hook = await req.json();
if (hook.type !== "video.asset.ready") {
return Response.json({ message: "Hey thanks, but ignoring this one." });
}
const playbackId = hook.data.playback_ids[0].id;
const output = await replicate.run(
model,
{
input: {
text: prompts.join(" | "),
image: `https://image.mux.com/${playbackId}/storyboard.jpg`,
},
},
);
const combinedObject = classes.reduce((obj, key, index) => {
obj[key[0]] = output[index];
return obj;
}, {});
console.log(combinedObject);
// await email({
// text: `
// Hey a new video just came in, here's the moderation report:
// Asset ID: ${hook.data.id}
// Playback ID: ${playbackId}
// ${classes.map((c, i) => `${c[0]}: ${output[i]}`).join("\n")}
// `,
// });
try {
await addVideo(hook.data, combinedObject);
} catch (err) {
// If something blew up at some point, we could end up in a situation where this has been saved...
console.log(err);
}
return Response.json({ ok: true });
}
1
2
3
export function myApi(name) {
return "hi " + name;
}
Next