forked from cloudflare/serverless-registry
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
93 lines (79 loc) · 2.78 KB
/
index.ts
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**
* The core server that runs on a Cloudflare worker.
*/
import { Router } from "itty-router";
import { AuthErrorResponse, InternalError } from "./src/errors";
import v2Router from "./src/router";
import { authenticationMethodFromEnv } from "./src/authentication-method";
import { Registry } from "./src/registry/registry";
import { R2Registry } from "./src/registry/r2";
// A full compatibility mode means that the r2 registry will try its best to
// help the client on the layer push. See how we let the client push layers with chunked uploads for more information.
type PushCompatibilityMode = "full" | "none";
export interface Env {
REGISTRY: R2Bucket;
ENVIRONMENT: string;
JWT_REGISTRY_TOKENS_PUBLIC_KEY?: string;
USERNAME?: string;
PASSWORD?: string;
READONLY_USERNAME?: string;
READONLY_PASSWORD?: string;
PUSH_COMPATIBILITY_MODE?: PushCompatibilityMode;
REGISTRIES_JSON?: string; // should be in the format of RegistryConfiguration[];
REGISTRY_CLIENT: Registry;
}
const router = Router();
/**
* V2 Api
*/
router.all("/v2/*", v2Router.handle);
router.all("*", () => new Response("Not Found.", { status: 404 }));
export default {
async fetch(request: Request, env: Env, context?: ExecutionContext) {
if (!ensureConfig(env)) {
return new AuthErrorResponse(request);
}
const authMethod = await authenticationMethodFromEnv(env);
if (!authMethod) {
return new AuthErrorResponse(request);
}
const credentials = await authMethod.checkCredentials(request);
if (!credentials.verified) {
console.warn(`Not Authorized. authmode=${authMethod.authmode}. verified=false`);
return new AuthErrorResponse(request);
}
env.REGISTRY_CLIENT = new R2Registry(env);
try {
// Dispatch the request to the appropriate route
const res = await router.handle(request, env, context);
return res;
} catch (err) {
if (err instanceof Response) {
console.warn(`${request.method} ${err.status} ${err.url}`);
return err;
}
// Unexpected error
if (err instanceof Error) {
console.error(
"An error has been thrown by the router:\n",
`${err.name}: ${err.message}: ${err.cause}: ${err.stack}`,
);
return new InternalError();
}
console.error(
"An error has been thrown and is neither a Response or an Error, JSON.stringify() =",
JSON.stringify(err),
);
return new InternalError();
}
},
} satisfies ExportedHandler<Env>;
const ensureConfig = (env: Env): boolean => {
if (!env.REGISTRY) {
console.error(
"env.REGISTRY is not setup. Please setup an R2 bucket and add the binding in wrangler.toml. Try 'npx wrangler --env production r2 bucket create r2-registry'",
);
return false;
}
return true;
};