Skip to content

Commit 6cdaec0

Browse files
Allow gitpod:// (#117)
1 parent f5b3e64 commit 6cdaec0

File tree

5 files changed

+53
-18
lines changed

5 files changed

+53
-18
lines changed

src/components/forms/Button.tsx

+2-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import React, { forwardRef, type FC, type ForwardedRef, type ReactNode } from "r
44
export type ButtonProps = {
55
type?: "primary" | "secondary" | "danger" | "danger.secondary" | "transparent";
66
size?: "small" | "medium" | "block";
7-
spacing?: "compact" | "default";
87
disabled?: boolean;
98
className?: string;
109
autoFocus?: boolean;
@@ -27,7 +26,6 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
2726
disabled = false,
2827
autoFocus = false,
2928
size,
30-
spacing = "default",
3129
icon,
3230
children,
3331
onClick,
@@ -38,14 +36,10 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
3836
<button
3937
type={htmlType}
4038
className={classNames(
41-
"cursor-pointer my-auto",
42-
"text-sm font-medium whitespace-nowrap",
43-
"rounded-xl focus:outline-none focus:ring transition ease-in-out",
44-
spacing === "compact" ? ["px-1 py-1"] : null,
45-
spacing === "default" ? ["px-4 py-2"] : null,
39+
"inline-flex items-center whitespace-nowrap rounded-lg text-sm justify-center font-medium transition-colors focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 h-9 px-4 py-2",
4640
type === "primary" ?
4741
[
48-
"bg-gray-900 hover:bg-gray-800 dark:bg-kumquat-base dark:hover:bg-kumquat-ripe",
42+
"bg-gray-900 hover:bg-gray-800 dark:bg-kumquat-base dark:hover:bg-kumquat-ripe text-gray-50 dark:text-gray-900",
4943
"text-gray-50 dark:text-gray-900",
5044
]
5145
: null,

src/popup.tsx

+5-3
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ function IndexPopup() {
4747
setJustSaved(true);
4848
});
4949

50-
browser.permissions.request({ origins: [origin] }).catch((e) => {
51-
setError(e.message);
52-
});
50+
if (origin) {
51+
browser.permissions.request({ origins: [origin] }).catch((e) => {
52+
setError(e.message);
53+
});
54+
}
5355
} catch (e) {
5456
setError(e.message);
5557
}

src/utils/parse-endpoint.spec.ts

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { expect } from "chai";
2+
3+
import { hostToOrigin, parseEndpoint } from "./parse-endpoint";
4+
5+
describe("parseEndpoint", () => {
6+
it("parses valid hosts", () => {
7+
expect(parseEndpoint("https://gitpod.io/new")).to.equal("https://gitpod.io");
8+
expect(parseEndpoint("gitpod.io")).to.equal("https://gitpod.io");
9+
expect(parseEndpoint("gitpod.io/new")).to.equal("https://gitpod.io");
10+
expect(parseEndpoint("gitpod://")).to.equal("gitpod://");
11+
expect(parseEndpoint("http://localhost:3000")).to.equal("http://localhost:3000");
12+
});
13+
14+
it("does not parse invalid hosts", () => {
15+
expect(() => parseEndpoint("gitpod")).to.throw(TypeError);
16+
expect(() => parseEndpoint("ftp://gitpod.io")).to.throw(TypeError);
17+
});
18+
});
19+
20+
describe("hostToOrigin", () => {
21+
it("converts hosts to origins", () => {
22+
expect(hostToOrigin("https://gitpod.io")).to.equal("https://gitpod.io/*");
23+
expect(hostToOrigin("http://localhost:3000")).to.equal("http://localhost:3000/*");
24+
});
25+
26+
it("does not convert invalid hosts", () => {
27+
expect(hostToOrigin("ftp://gitpod.io")).to.be.undefined;
28+
expect(hostToOrigin("gitpod://")).to.be.undefined;
29+
});
30+
});

src/utils/parse-endpoint.ts

+14-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import isUrl from "validator/es/lib/isURL";
22

3+
const allowedProtocols = ["http:", "https:", "gitpod:"];
4+
35
export const parseEndpoint = (input: string): string => {
46
let url: URL;
57

6-
if (isUrl(input, { require_protocol: true, protocols: ["https"] })) {
7-
url = new URL(input);
8-
} else if (isUrl(input, { require_protocol: true, protocols: ["https", "http"], host_whitelist: ["localhost"] })) {
8+
if (URL.canParse(input)) {
99
url = new URL(input);
10-
} else if (isUrl(input, { require_protocol: false, protocols: ["https"] })) {
10+
11+
if (!allowedProtocols.includes(url.protocol)) {
12+
throw new TypeError(`Invalid protocol in URL: ${input}`);
13+
}
14+
} else if (isUrl(input, { require_protocol: false, protocols: ["http", "https", "gitpod"] })) {
1115
url = new URL(`https://${input}`);
1216
} else {
1317
throw new TypeError(`Invalid URL: ${input}`);
@@ -16,8 +20,11 @@ export const parseEndpoint = (input: string): string => {
1620
return `${url.protocol}//${url.host}`;
1721
};
1822

19-
export const hostToOrigin = (host: string): string => {
20-
const url = new URL(host);
23+
export const hostToOrigin = (host: string): string | undefined => {
24+
const { origin, protocol } = new URL(host);
25+
if (origin === "null" || !["http:", "https:"].includes(protocol)) {
26+
return undefined;
27+
}
2128

22-
return url.origin + "/*";
29+
return `${origin}/*`;
2330
};

tailwind.config.js

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ module.exports = {
77
extend: {
88
colors: {
99
"gitpod-black": "#161616",
10+
"kumquat-base": "#FFAE33",
11+
"kumquat-ripe": "#FFB45B",
1012
"gitpod-red": "#CE4A3E",
1113
},
1214
},

0 commit comments

Comments
 (0)