-
-
Notifications
You must be signed in to change notification settings - Fork 131
fix(frontend): plan page dark-mode loader and checkout popup #2900
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,13 +28,42 @@ async function presentActionSheetOpen(url: string) { | |
| }) | ||
| return dialogStore.onDialogDismiss() | ||
| } | ||
| export function openBlank(link: string) { | ||
| async function presentBlockedPopupFallback(url: string) { | ||
| const { t } = useI18n() | ||
| const dialogStore = useDialogV2Store() | ||
|
|
||
| dialogStore.openDialog({ | ||
| title: t('open-in-new-tab'), | ||
| description: t('popup-blocked-open-manually'), | ||
| buttons: [ | ||
| { | ||
| text: t('button-cancel'), | ||
| role: 'cancel', | ||
| }, | ||
| { | ||
| text: t('button-confirm'), | ||
| id: 'confirm-button', | ||
| role: 'primary', | ||
| href: url, | ||
| target: '_blank', | ||
| rel: 'noopener noreferrer', | ||
| }, | ||
| ], | ||
| }) | ||
| return !(await dialogStore.onDialogDismiss()) | ||
| } | ||
|
|
||
| export async function openBlank(link: string) { | ||
| console.log('openBlank', link) | ||
| if (Capacitor.getPlatform() === 'ios') { | ||
| presentActionSheetOpen(link) | ||
| return true | ||
| // presentActionSheetOpen resolves true when dismissed/canceled | ||
| return !(await presentActionSheetOpen(link)) | ||
| } | ||
| return Boolean(globalThis.open(link, '_blank')) | ||
| const opened = globalThis.open(link, '_blank') | ||
| if (opened) | ||
| return true | ||
|
Comment on lines
+62
to
+64
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- src/services/stripe.ts ---'
cat -n src/services/stripe.ts
printf '%s\n' '--- window.open usages ---'
rg -n -C 3 'globalThis\.open|window\.open|noopener|opener' src tests .github 2>/dev/null || true
printf '%s\n' '--- relevant package/runtime metadata ---'
rg -n -C 2 '"(lint|test|typecheck|build)"|vue|vite|vitest|playwright' package.json bun.lockb package-lock.json yarn.lock pnpm-lock.yaml 2>/dev/null || trueRepository: Cap-go/capgo.app Length of output: 36115 🌐 Web query:
💡 Result: In modern web browsers, setting target="_blank" on , , or elements implicitly behaves as if rel="noopener" has been specified [1]. This means the opened browsing context will not have access to the opening window via the window.opener property, which will return null [2][1]. This implicit behavior was standardized to improve security by preventing the opened page from tampering with the original page via the window.opener reference [1][3]. If you explicitly require window.opener access, you must now use rel="opener" on the link [1][3]. Browser Compatibility: This implicit behavior is widely supported in modern browsers [4]. Support for target="_blank" implying rel="noopener" generally aligns with the adoption of this standard in major browser engines (Chromium 88+, Firefox 79+, and Safari 12.1+) [4]. Older browsers do not provide this implicit security, which is why developers previously had to manually add rel="noopener" to secure links [3][5]. Note: This implicit behavior applies to HTML anchor/form elements [1]. When using the window.open JavaScript method, the noopener behavior is not automatic and must still be explicitly requested by including "noopener" in the windowFeatures parameter [6][7].Citations:
🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- browser-target and compatibility configuration ---'
rg -n -i -C 2 'browserslist|browser|target|support|compatib' package.json vite.config.* .browserslistrc tsconfig*.json README.md docs 2>/dev/null || true
printf '%s\n' '--- tests and history for openBlank ---'
rg -n -C 5 'openBlank|presentBlockedPopupFallback|window\.opener' tests src scripts 2>/dev/null || true
git diff --stat
git log --oneline -8 -- src/services/stripe.tsRepository: Cap-go/capgo.app Length of output: 50375 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- browser support configuration ---'
for f in package.json vite.config.ts vite.config.js vite.config.mts .browserslistrc; do
if [ -f "$f" ]; then
printf '\n[%s]\n' "$f"
rg -n -i 'browserslist|target|browser|support|compatib' "$f" || true
fi
done
printf '%s\n' '--- focused openBlank history ---'
git log --oneline -12 -- src/services/stripe.ts
printf '%s\n' '--- focused tests/usages ---'
rg -n -C 4 'openBlank|presentActionSheetOpen|window\.opener' tests src/services src/pages/app/'[app]'.channel.'[channel]'.vue 2>/dev/null || true
printf '%s\n' '--- current diff summary ---'
git diff --statRepository: Cap-go/capgo.app Length of output: 3274 🏁 Script executed (no clone): Length of output: 169 🌐 Web query:
💡 Result: When the Citations:
Clear 🤖 Prompt for AI Agents |
||
| // Async callers often lose the user-gesture; offer a confirm link fallback. | ||
| return presentBlockedPopupFallback(link) | ||
| } | ||
| export async function openPortal(orgId: string, t: ComposerTranslation) { | ||
| let url = '' | ||
|
|
@@ -70,7 +99,7 @@ export async function openPortal(orgId: string, t: ComposerTranslation) { | |
| handler: async () => { | ||
| await prem | ||
| if (url) | ||
| openBlank(url) | ||
| await openBlank(url) | ||
| else | ||
| toast.error('Cannot open your portal') | ||
| }, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Reading the Confirm link's href and navigating with page.goto bypasses the actual target=_blank popup this PR is meant to harden, so the new
_blankopen path and popup-blocker fallback are never e2e-covered. Consider clicking the link and asserting the resulting popup (e.g.const [popup] = await Promise.all([page.waitForEvent('popup'), confirmLink.click()]), then assertpopup.url()matches the Stripe origin) so a regression in DialogV2's native-blank handling is caught.Prompt for AI agents