From 8f53f3b28c57f77eb0472a4fb7290a40d6aa58e1 Mon Sep 17 00:00:00 2001 From: Andrew Smith Date: Tue, 28 Nov 2023 00:35:37 +1100 Subject: [PATCH] Allow embedding of GitLab snippets (#6217) --- public/images/gitlab.png | Bin 0 -> 6438 bytes server/services/web.ts | 14 ++++++-- shared/editor/embeds/GitLabSnippet.test.ts | 31 +++++++++++++++++ shared/editor/embeds/GitLabSnippet.tsx | 38 +++++++++++++++++++++ shared/editor/embeds/index.tsx | 7 ++++ 5 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 public/images/gitlab.png create mode 100644 shared/editor/embeds/GitLabSnippet.test.ts create mode 100644 shared/editor/embeds/GitLabSnippet.tsx diff --git a/public/images/gitlab.png b/public/images/gitlab.png new file mode 100644 index 0000000000000000000000000000000000000000..85ec9e76f69fc7b74f08eae523d8d18d6bebef36 GIT binary patch literal 6438 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 Utgki)AGT^NcOPbzTX53<0C;=KHUIzs literal 0 HcmV?d00001 diff --git a/server/services/web.ts b/server/services/web.ts index c54e14b0d..76adabea4 100644 --- a/server/services/web.ts +++ b/server/services/web.ts @@ -24,9 +24,19 @@ import auth from "../routes/auth"; // Construct scripts CSP based on services in use by this installation const defaultSrc = ["'self'"]; -const scriptSrc = ["'self'", "gist.github.com", "www.googletagmanager.com"]; +const scriptSrc = [ + "'self'", + "gist.github.com", + "www.googletagmanager.com", + "gitlab.com", +]; -const styleSrc = ["'self'", "'unsafe-inline'", "github.githubassets.com"]; +const styleSrc = [ + "'self'", + "'unsafe-inline'", + "github.githubassets.com", + "gitlab.com", +]; if (env.isCloudHosted) { scriptSrc.push("cdn.zapier.com"); diff --git a/shared/editor/embeds/GitLabSnippet.test.ts b/shared/editor/embeds/GitLabSnippet.test.ts new file mode 100644 index 000000000..fbd1d5b90 --- /dev/null +++ b/shared/editor/embeds/GitLabSnippet.test.ts @@ -0,0 +1,31 @@ +import GitLabSnippet from "./GitLabSnippet"; + +describe("GitLabSnippet", () => { + const match = GitLabSnippet.ENABLED[0]; + + test("to be enabled on snippet link", () => { + expect("https://gitlab.com/-/snippets/1234".match(match)).toBeTruthy(); + expect( + "https://gitlab.com/gitlab-org/gitlab/-/snippets/2256824".match(match) + ).toBeTruthy(); + expect( + "https://gitlab.com/group/project/sub-project/sub-sub-project/test/-/snippets/9876".match( + match + ) + ).toBeTruthy(); + }); + + test("to not be enabled elsewhere", () => { + expect("https://gitlab.com".match(match)).toBe(null); + expect("https://gitlab.com/gitlab-org".match(match)).toBe(null); + expect("https://gitlab.com/gitlab-org/gitlab".match(match)).toBe(null); + expect("https://gitlab.com/gitlab-org/gitlab/-/issues".match(match)).toBe( + null + ); + expect( + "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/137948".match( + match + ) + ).toBe(null); + }); +}); diff --git a/shared/editor/embeds/GitLabSnippet.tsx b/shared/editor/embeds/GitLabSnippet.tsx new file mode 100644 index 000000000..05bb38883 --- /dev/null +++ b/shared/editor/embeds/GitLabSnippet.tsx @@ -0,0 +1,38 @@ +import * as React from "react"; +import styled from "styled-components"; +import { EmbedProps as Props } from "."; + +const GITLAB_NAMESPACE_REGEX = "(([a-zA-Z\\d-]+)/)"; + +const Iframe = styled.iframe` + margin-top: 8px; +`; + +function GitLabSnippet(props: Props) { + const snippetUrl = new URL(props.attrs.href); + const id = snippetUrl.pathname.split("/").pop(); + const snippetLink = `${snippetUrl}.js`; + const snippetScript = ``; + const styles = ""; + const iframeHtml = `${styles}${snippetScript}`; + + return ( +