MCPcopy
hub / github.com/CapSoftware/Cap / validateExtensionRedirectUri

Function validateExtensionRedirectUri

packages/web-backend/src/Extension/Http.ts:25–67  ·  view source on GitHub ↗
(redirectUri: string)

Source from the content-addressed store, hash-verified

23const CHROMIUM_IDENTITY_HOST_SUFFIX = ".chromiumapp.org";
24
25const validateExtensionRedirectUri = (redirectUri: string) =>
26 Effect.gen(function* () {
27 const url = yield* Effect.try({
28 try: () => new URL(redirectUri),
29 catch: () => new HttpApiError.BadRequest(),
30 });
31
32 if (
33 url.protocol !== "https:" ||
34 !url.hostname.endsWith(CHROMIUM_IDENTITY_HOST_SUFFIX)
35 ) {
36 return yield* new HttpApiError.BadRequest();
37 }
38
39 const extensionId = url.hostname.slice(
40 0,
41 -CHROMIUM_IDENTITY_HOST_SUFFIX.length,
42 );
43 const configuredExtensionId = serverEnv().CAP_CHROME_EXTENSION_ID;
44
45 if (configuredExtensionId) {
46 if (extensionId !== configuredExtensionId) {
47 return yield* new HttpApiError.BadRequest();
48 }
49 return url;
50 }
51
52 // Without a pinned extension id, any installed extension could mint a
53 // signed-in user's auth key through this flow. The only deployment
54 // where accepting an arbitrary id is safe is localhost development;
55 // every reachable deployment (staging, previews, self-hosted) must set
56 // CAP_CHROME_EXTENSION_ID regardless of NODE_ENV.
57 const webHostname = new URL(serverEnv().WEB_URL).hostname;
58 const isLocalDevelopment =
59 serverEnv().NODE_ENV !== "production" &&
60 (webHostname === "localhost" || webHostname === "127.0.0.1");
61
62 if (!isLocalDevelopment) {
63 return yield* new HttpApiError.BadRequest();
64 }
65
66 return url;
67 });
68
69const redirectToLogin = (nextUrl: URL) => {
70 const loginUrl = new URL("/login", serverEnv().WEB_URL);

Callers 1

Http.tsFile · 0.85

Calls 1

serverEnvFunction · 0.90

Tested by

no test coverage detected