Skip to content

Commit 42ec6c4

Browse files
Default domain restriction (#101)
1 parent 9dc077e commit 42ec6c4

File tree

14 files changed

+595
-73
lines changed

14 files changed

+595
-73
lines changed

.github/workflows/submit.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,21 @@ jobs:
4747
- name: Build the extension (Chrome)
4848
run: pnpm plasmo build --target=chrome-mv3
4949
- name: Build the extension (Firefox)
50-
run: pnpm plasmo build --target=firefox-mv2
50+
run: |
51+
jq '.manifest.host_permissions = .manifest.optional_host_permissions | del(.manifest.optional_host_permissions)' package.json > temp.json && mv temp.json package.json # fix incomatibility with Chrome's MV3. See https://bugzilla.mozilla.org/show_bug.cgi?id=1766026
52+
pnpm plasmo build --target=firefox-mv3
5153
- name: Package the extension into zip artifacts
5254
run: |
5355
pnpm package --target=chrome-mv3
54-
pnpm package --target=firefox-mv2
56+
pnpm package --target=firefox-mv3
5557
- name: Browser Platform Publish (staging)
5658
uses: PlasmoHQ/bpp@v3
5759
if: env.CHANNEL == 'staging'
5860
with:
5961
keys: ${{ secrets.SUBMIT_KEYS_STAGING }}
6062
verbose: true
6163
chrome-file: build/chrome-mv3-prod.zip
62-
firefox-file: build/firefox-mv2-prod.zip
64+
firefox-file: build/firefox-mv3-prod.zip
6365
- name: Browser Platform Publish (production)
6466
uses: PlasmoHQ/bpp@v3
6567
if: env.CHANNEL == 'production'

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[![Setup Automated](https://img.shields.io/badge/setup-automated-blue?logo=gitpod)](https://gitpod.io/#https://github.com/gitpod-io/browser-extension)
44

5-
This is the browser extension for Gitpod. It supports Chrome (see [Chrome Web Store](https://chrome.google.com/webstore/detail/dodmmooeoklaejobgleioelladacbeki/)), Firefox (see [Firefox Add-ons](https://addons.mozilla.org/firefox/addon/gitpod/)) and Edge (see [how to install Chrome extensions](https://support.microsoft.com/help/4538971/microsoft-edge-add-or-remove-extensions)), and adds a **Gitpod** button to the configured GitLab, GitHub and Bitbucket installations (defaults to `gitlab.com`, `github.com`, `bitbucket.org`, and `gitlab.cn`) which immediately creates a Gitpod workspace for the current Git context:
5+
This is the browser extension for Gitpod. It supports Chrome (see [Chrome Web Store](https://chrome.google.com/webstore/detail/dodmmooeoklaejobgleioelladacbeki/)), Firefox (see [Firefox Add-ons](https://addons.mozilla.org/firefox/addon/gitpod/)) and Edge (see [how to install Chrome extensions](https://support.microsoft.com/help/4538971/microsoft-edge-add-or-remove-extensions)), and adds a **Gitpod** button to the configured GitLab, GitHub and Bitbucket installations (defaults to `gitlab.com`, `github.com` and `bitbucket.org`) which immediately creates a Gitpod workspace for the current git context:
66

77
![Gitpodify](./docs/github-injected.png "Gitpodify")
88

package.json

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,15 @@
2323
"plasmo": "^0.83.0",
2424
"react": "^18.2.0",
2525
"react-dom": "^18.2.0",
26-
"validator": "^13.11.0"
26+
"validator": "^13.11.0",
27+
"webext-additional-permissions": "^2.4.0",
28+
"webext-content-scripts": "^2.5.5",
29+
"webext-detect-page": "^4.1.1",
30+
"webext-dynamic-content-scripts": "v9",
31+
"webext-patterns": "^1.3.0",
32+
"webext-polyfill-kinda": "^1.0.2",
33+
"webext-tools": "^1.1.4",
34+
"webextension-polyfill-ts": "^0.26.0"
2735
},
2836
"devDependencies": {
2937
"@ianvs/prettier-plugin-sort-imports": "4.1.0",
@@ -51,13 +59,18 @@
5159
"typescript": "5.1.6"
5260
},
5361
"manifest": {
54-
"host_permissions": [
55-
"https://*/*"
62+
"optional_host_permissions": [
63+
"*://*/*"
64+
],
65+
"permissions": [
66+
"scripting",
67+
"contextMenus",
68+
"activeTab"
5669
],
5770
"browser_specific_settings": {
5871
"gecko": {
59-
"id": "$FIREFOX_EXT_ID"
72+
"id": "{24229a4f-eecc-47dc-abad-e47674ea8169}"
6073
}
6174
}
6275
}
63-
}
76+
}

pnpm-lock.yaml

Lines changed: 101 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/background.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,14 @@
1+
import { browser } from "webextension-polyfill-ts";
2+
import 'webext-dynamic-content-scripts';
3+
import addDomainPermissionToggle from "~utils/domain-accept";
4+
5+
addDomainPermissionToggle();
6+
7+
browser.runtime.onInstalled.addListener((details) => {
8+
if (details.reason === "install") {
9+
browser.tabs.create({ url: "https://www.gitpod.io/extension-activation?track=true" });
10+
}
11+
});
12+
browser.runtime.setUninstallURL("https://www.gitpod.io/extension-uninstall?track=true");
13+
114
export { }

src/components/forms/Button.tsx

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import classNames from "classnames"
2+
import React, {
3+
forwardRef,
4+
type FC,
5+
type ForwardedRef,
6+
type ReactNode
7+
} from "react"
8+
9+
export type ButtonProps = {
10+
type?: "primary" | "secondary" | "danger" | "danger.secondary" | "transparent"
11+
size?: "small" | "medium" | "block"
12+
spacing?: "compact" | "default"
13+
disabled?: boolean
14+
className?: string
15+
autoFocus?: boolean
16+
htmlType?: "button" | "submit" | "reset"
17+
icon?: ReactNode
18+
children?: ReactNode
19+
onClick?: ButtonOnClickHandler
20+
}
21+
22+
// Allow w/ or w/o handling event argument
23+
type ButtonOnClickHandler =
24+
| React.DOMAttributes<HTMLButtonElement>["onClick"]
25+
| (() => void)
26+
27+
// eslint-disable-next-line react/display-name
28+
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
29+
(
30+
{
31+
type = "primary",
32+
className,
33+
htmlType = "button",
34+
disabled = false,
35+
autoFocus = false,
36+
size,
37+
spacing = "default",
38+
icon,
39+
children,
40+
onClick
41+
},
42+
ref: ForwardedRef<HTMLButtonElement>
43+
) => {
44+
return (
45+
<button
46+
type={htmlType}
47+
className={classNames(
48+
"cursor-pointer my-auto",
49+
"text-sm font-medium whitespace-nowrap",
50+
"rounded-xl focus:outline-none focus:ring transition ease-in-out",
51+
spacing === "compact" ? ["px-1 py-1"] : null,
52+
spacing === "default" ? ["px-4 py-2"] : null,
53+
type === "primary"
54+
? [
55+
"bg-gray-900 hover:bg-gray-800 dark:bg-kumquat-base dark:hover:bg-kumquat-ripe",
56+
"text-gray-50 dark:text-gray-900"
57+
]
58+
: null,
59+
type === "secondary"
60+
? [
61+
"bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600",
62+
"text-gray-500 dark:text-gray-100 hover:text-gray-600"
63+
]
64+
: null,
65+
type === "danger"
66+
? ["bg-red-600 hover:bg-red-700", "text-gray-100 dark:text-red-100"]
67+
: null,
68+
type === "danger.secondary"
69+
? [
70+
"bg-red-50 dark:bg-red-300 hover:bg-red-100 dark:hover:bg-red-200",
71+
"text-red-600 hover:text-red-700"
72+
]
73+
: null,
74+
type === "transparent"
75+
? [
76+
"bg-transparent hover:bg-gray-600 hover:bg-opacity-10 dark:hover:bg-gray-200 dark:hover:bg-opacity-10"
77+
]
78+
: null,
79+
{
80+
"w-full": size === "block",
81+
"cursor-default opacity-50 pointer-events-none": disabled
82+
},
83+
className
84+
)}
85+
ref={ref}
86+
disabled={disabled}
87+
autoFocus={autoFocus}
88+
onClick={onClick}>
89+
<ButtonContent icon={icon}>{children}</ButtonContent>
90+
</button>
91+
)
92+
}
93+
)
94+
95+
// TODO: Consider making this a LoadingButton variant instead
96+
type ButtonContentProps = {
97+
icon?: ReactNode
98+
children?: ReactNode
99+
}
100+
const ButtonContent: FC<ButtonContentProps> = ({ icon, children }) => {
101+
if (!icon) {
102+
return <span>{children}</span>
103+
}
104+
105+
return (
106+
<div className="flex items-center justify-center space-x-2">
107+
<span className="flex justify-center items-center w-5 h-5">
108+
{icon ? icon : null}
109+
</span>
110+
{children && <span>{children}</span>}
111+
</div>
112+
)
113+
}

src/constants.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
export const DEFAULT_GITPOD_ENDPOINT = "https://gitpod.io";
1+
export const DEFAULT_GITPOD_ENDPOINT = "https://gitpod.io";
2+
export const ALL_ORIGINS_WILDCARD = "*://*/*";

src/contents/button.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
import cssText from "data-text:../button/button.css";
12
import type { PlasmoCSConfig, PlasmoGetInlineAnchor } from "plasmo";
2-
import cssText from "data-text:../button/button.css"
3-
import { buttonContributions, type ButtonContributionParams, isSiteSuitable } from "../button/button-contributions";
3+
import React, { type ReactElement } from "react";
44
import { GitpodButton } from "../button/button";
5-
import { type ReactElement } from "react";
6-
import React from "react";
5+
import { buttonContributions, isSiteSuitable, type ButtonContributionParams } from "../button/button-contributions";
76

87
export const config: PlasmoCSConfig = {
9-
matches: ["<all_urls>"]
8+
matches: [
9+
"https://github.com/*",
10+
"https://gitlab.com/*",
11+
"https://bitbucket.org/*",
12+
]
1013
}
1114

1215
export const getStyle = () => {

src/contents/gitpod-dashboard.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import type { PlasmoCSConfig } from "plasmo";
21
import { Storage } from "@plasmohq/storage";
2+
import type { PlasmoCSConfig } from "plasmo";
3+
import { DEFAULT_GITPOD_ENDPOINT } from "~constants";
34
import { STORAGE_AUTOMATICALLY_DETECT_GITPOD, STORAGE_KEY_ADDRESS } from "~storage";
45
import { parseEndpoint } from "~utils/parse-endpoint";
5-
import { DEFAULT_GITPOD_ENDPOINT } from "~constants";
66

77
/**
88
* Checks if the current site is a Gitpod instance.
@@ -12,7 +12,11 @@ const isSiteGitpod = (): boolean => {
1212
}
1313

1414
export const config: PlasmoCSConfig = {
15-
matches: ["https://*/*"]
15+
matches: [
16+
"https://gitpod.io/*",
17+
"https://*.gitpod.cloud/*",
18+
"https://*.gitpod.dev/*"
19+
],
1620
}
1721

1822
const storage = new Storage();
@@ -21,16 +25,14 @@ const automaticallyUpdateEndpoint = async () => {
2125
if (await storage.get<boolean>(STORAGE_AUTOMATICALLY_DETECT_GITPOD) === false) {
2226
return;
2327
}
24-
25-
const currentUserSetEndpoint = await storage.get(STORAGE_KEY_ADDRESS);
26-
if (!currentUserSetEndpoint || currentUserSetEndpoint === DEFAULT_GITPOD_ENDPOINT) {
27-
const currentHost = window.location.host;
28-
if (currentHost !== new URL(DEFAULT_GITPOD_ENDPOINT).host) {
29-
console.log(`Gitpod extension: switching default endpoint to ${currentHost}.`)
30-
await storage.set(STORAGE_KEY_ADDRESS, parseEndpoint(currentHost));
31-
}
28+
29+
const currentHost = window.location.host;
30+
if (currentHost !== new URL(DEFAULT_GITPOD_ENDPOINT).host) {
31+
console.log(`Gitpod extension: switching default endpoint to ${currentHost}.`)
32+
await storage.set(STORAGE_KEY_ADDRESS, parseEndpoint(currentHost));
3233
}
3334
}
35+
3436
if (isSiteGitpod()) {
3537
sessionStorage.setItem("browser-extension-installed", "true");
3638
automaticallyUpdateEndpoint();

0 commit comments

Comments
 (0)