Skip to content

LC-2853 admin 블로그 글 에디터 개선 1#2132

Open
hyonun321 wants to merge 3 commits intoLC-2838-Sprint-17from
LC-2853-admin-블로그-글-에디터-개선-1

Hidden character warning

The head ref may contain hidden characters: "LC-2853-admin-\ube14\ub85c\uadf8-\uae00-\uc5d0\ub514\ud130-\uac1c\uc120-1"
Open

LC-2853 admin 블로그 글 에디터 개선 1#2132
hyonun321 wants to merge 3 commits intoLC-2838-Sprint-17from
LC-2853-admin-블로그-글-에디터-개선-1

Conversation

@hyonun321
Copy link
Contributor

@hyonun321 hyonun321 commented Feb 20, 2026

연관 작업

hyonun321 and others added 2 commits February 21, 2026 00:53
이미지 클릭 시 나타나는 리사이저 UI에 링크 버튼을 추가하여,
드래그 선택 없이도 이미지에 링크를 삽입/수정/제거할 수 있도록 개선

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@hyonun321 hyonun321 self-assigned this Feb 20, 2026
@github-actions github-actions bot changed the title Lc 2853 admin 블로그 글 에디터 개선 1 LC-2853 admin 블로그 글 에디터 개선 1 Feb 20, 2026
@gemini-code-assist
Copy link

Summary of Changes

Hello @hyonun321, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 관리자 블로그 글 에디터의 사용자 경험을 개선하기 위해 이미지에 링크를 추가하고 관리하는 기능을 도입합니다. 또한, 이미지 관련 액션 버튼들의 레이아웃을 개선하고, 에디터 내 단락 간의 시각적 구분을 명확히 하여 전반적인 글쓰기 환경을 향상시키는 데 중점을 둡니다.

Highlights

  • 이미지 링크 기능 추가: Lexical 에디터 내 이미지에 링크를 추가, 수정, 제거할 수 있는 기능이 구현되었습니다.
  • 이미지 액션 버튼 UI 개선: 이미지 리사이저에 캡션 추가 버튼과 새로 추가된 링크 버튼을 포함하는 새로운 액션 버튼 그룹이 도입되어 중앙 정렬되고 간격이 조정되었습니다.
  • 단락 마진 조정: 에디터 내 단락 요소의 하단 마진이 추가되어 가독성이 향상되었습니다.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/domain/admin/lexical/index.css
    • 이미지 액션 버튼들을 위한 새로운 스타일이 추가되었습니다.
    • 이미지 캡션 버튼과 링크 버튼의 스타일이 통합 및 조정되었습니다.
    • 이미지 액션 버튼들의 호버 효과가 확장되었습니다.
  • src/domain/admin/lexical/nodes/ImageComponent.tsx
    • Lexical LinkNode 관련 유틸리티 함수들이 임포트되었습니다.
    • 이미지에 링크를 추가, 수정, 제거하는 handleLinkClick 함수가 구현되었습니다.
    • ImageResizer 컴포넌트에 onLinkClick 콜백이 전달되도록 업데이트되었습니다.
  • src/domain/admin/lexical/themes/PlaygroundEditorTheme.css
    • 단락 요소에 하단 마진이 추가되었습니다.
  • src/domain/admin/lexical/ui/ImageResizer.tsx
    • onLinkClick prop이 추가되었습니다.
    • 캡션 추가 버튼과 링크 버튼을 포함하는 image-action-buttons 컨테이너가 추가되었습니다.
    • 이미지에 링크를 설정할 수 있는 '링크' 버튼이 추가되었습니다.
Activity
  • 이 PR에는 아직 활동이 없습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This PR implements the functionality to add and edit links to images in the admin blog editor. While this is a good improvement, a high-severity stored Cross-Site Scripting (XSS) vulnerability has been identified. User-supplied URLs for image links are not being sanitized, which allows for the injection of malicious javascript: payloads. Additionally, it is recommended to replace window.prompt with a custom modal for URL input to provide a consistent UI and facilitate better URL validation, which would also help mitigate the XSS vulnerability.

Comment on lines +381 to +407
const url = window.prompt('링크 URL을 입력하세요', currentUrl);
if (url === null) return;

editor.update(() => {
const node = $getNodeByKey(nodeKey);
if (!node) return;
const parent = node.getParent();
if (!parent) return;

if (url === '') {
// 링크 제거: LinkNode를 벗기고 자식을 꺼냄
if ($isLinkNode(parent)) {
const children = parent.getChildren();
for (const child of children) {
parent.insertBefore(child);
}
parent.remove();
}
} else if ($isLinkNode(parent)) {
// 기존 링크 URL 수정
parent.setURL(url);
} else {
// 새 링크 추가: LinkNode로 이미지를 감쌈
const linkNode = $createLinkNode(url);
node.insertBefore(linkNode);
linkNode.append(node);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

A stored Cross-Site Scripting (XSS) vulnerability exists in the handleLinkClick function. The application uses window.prompt to get a URL from the user to add a link to an image. The input from this prompt is not sanitized before being used to create or update a LinkNode. An attacker can input a malicious URL containing a javascript: payload (e.g., javascript:alert('XSS')). This payload is then stored as part of the editor's content, leading to arbitrary code execution when clicked. Beyond the security risk, using window.prompt negatively impacts user experience due to inconsistent UI and lack of styling options. It also makes it difficult to add robust URL validation. It is strongly recommended to replace window.prompt with a custom modal (e.g., using useModal) for a consistent UI/UX and to integrate proper URL validation, similar to validateUrl in LinkPlugin, to prevent such vulnerabilities.

    const url = window.prompt('링크 URL을 입력하세요', currentUrl);
    if (url === null) return;

    // TODO: Import a URL sanitization function
    const sanitizedUrl = new URL(url).href.startsWith('javascript:') ? '' : url;

    editor.update(() => {
      const node = $getNodeByKey(nodeKey);
      if (!node) return;
      const parent = node.getParent();
      if (!parent) return;

      if (sanitizedUrl === '') {
        // 링크 제거: LinkNode를 벗기고 자식을 꺼냄
        if ($isLinkNode(parent)) {
          const children = parent.getChildren();
          for (const child of children) {
            parent.insertBefore(child);
          }
          parent.remove();
        }
      } else if ($isLinkNode(parent)) {
        // 기존 링크 URL 수정
        parent.setURL(sanitizedUrl);
      } else {
        // 새 링크 추가: LinkNode로 이미지를 감쌈
        const linkNode = $createLinkNode(sanitizedUrl);
        node.insertBefore(linkNode);
        linkNode.append(node);
      }
    });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant