Skip to content

Commit 1552a2a

Browse files
committed
Merge branch '6.x' into fieldset-sections
2 parents 2966bdb + 466b2e8 commit 1552a2a

6 files changed

Lines changed: 72 additions & 14 deletions

File tree

resources/js/components/blueprints/ImportField.vue

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,20 @@
88
<div class="flex flex-1 items-center py-2">
99
<ui-icon class="size-4 me-2 text-ui-accent-text/80" name="fieldsets" />
1010
<div class="flex items-center gap-2">
11-
<!-- @TODO: Show fieldset.title -->
12-
<button class="cursor-pointer overflow-hidden text-ellipsis text-sm text-ui-accent-text hover:text-ui-accent-text/80" v-text="field.fieldset" @click="$emit('edit')" />
11+
<a class="cursor-pointer overflow-hidden text-ellipsis text-sm text-ui-accent-text hover:text-ui-accent-text/80" :href="fieldsetEditUrl" v-text="fieldsetTitle" v-tooltip="__('Edit fieldset')" />
1312
<ui-icon name="link" class="text-gray-400" />
1413
<span class="text-gray-500 font-mono text-2xs" v-text="__('Fieldset')" />
14+
<ui-badge
15+
v-if="field.prefix"
16+
size="sm"
17+
color="gray"
18+
:text="`${__('Prefix')}: ${field.prefix}`"
19+
/>
1520
</div>
1621
</div>
17-
<div class="flex items-center gap-2">
18-
<ui-button size="sm" icon="trash" variant="subtle" @click.prevent="$emit('deleted')" v-tooltip="__('Remove')" />
22+
<div class="flex items-center">
23+
<ui-button size="sm" icon="cog" variant="subtle" inset @click.prevent="$emit('edit')" v-tooltip="__('Configure import')" />
24+
<ui-button size="sm" icon="trash" variant="subtle" inset @click.prevent="$emit('deleted')" v-tooltip="__('Remove')" />
1925
<ui-stack :open="isEditing" @update:open="editorClosed" inset :show-close-button="false" :wrap-slot="false">
2026
<field-settings
2127
ref="settings"
@@ -50,6 +56,16 @@ export default {
5056
},
5157
5258
computed: {
59+
fieldsetTitle() {
60+
const title = this.$page?.props?.fieldsets?.[this.field.fieldset]?.title;
61+
62+
return title ? __(title) : this.field.fieldset;
63+
},
64+
65+
fieldsetEditUrl() {
66+
return cp_url(`fields/fieldsets/${this.field.fieldset}/edit`);
67+
},
68+
5369
fieldConfig() {
5470
const { _id, type, ...config } = this.field;
5571
return config;

resources/js/components/fieldtypes/bard/Set.vue

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
>
1919
<div ref="content" hidden />
2020
<header
21-
class="group/header animate-border-color show-focus-within flex items-center rounded-[calc(var(--radius-lg)-1px)] px-1.5 antialiased duration-200 bg-gray-100/50 dark:bg-gray-925 hover:bg-gray-100 dark:hover:bg-gray-950/45 border-gray-300 dark:shadow-md border-b-1 border-b-transparent"
21+
class="group/header animate-border-color show-focus-within flex items-center rounded-[calc(var(--radius-lg)-1px)] px-1.5 antialiased duration-200 bg-gray-100/50 dark:bg-gray-925 hover:bg-gray-100 dark:hover:bg-gray-950/45 border-gray-300 dark:shadow-md"
2222
:class="{
23-
'bg-gray-200/50 dark:bg-gray-950/35 rounded-b-none border-b-gray-300! dark:border-b-white/10!': !collapsed
23+
'bg-gray-200/50 dark:bg-gray-950/35 rounded-b-none': !collapsed && hasFields
2424
}"
2525
>
2626
<span v-if="!isReadOnly" data-drag-handle class="flex cursor-grab" @mousedown="enableDragging">
@@ -77,7 +77,12 @@
7777
</div>
7878
</header>
7979

80-
<div v-if="index !== undefined" v-show="!collapsed" :class="{ 'contain-paint': collapsed, 'isolate': !collapsed }">
80+
<div
81+
v-if="index !== undefined && hasFields"
82+
v-show="!collapsed"
83+
:class="{ 'contain-paint': collapsed, 'isolate': !collapsed }"
84+
class="border-t border-t-gray-300! dark:border-t-white/10!"
85+
>
8186
<FieldsProvider
8287
:fields="fields"
8388
:as-config="false"
@@ -143,6 +148,12 @@ export default {
143148
return this.config.fields;
144149
},
145150
151+
hasFields() {
152+
return Array.isArray(this.fields)
153+
? this.fields.length > 0
154+
: Object.keys(this.fields || {}).length > 0;
155+
},
156+
146157
display() {
147158
return __(this.config.display || this.values.type);
148159
},

resources/js/components/fieldtypes/replicator/Set.vue

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const {
4848
const fieldPathPrefix = computed(() => `${props.fieldPath}.${props.index}`);
4949
const metaPathPrefix = computed(() => `${props.metaPath}.existing.${props.id}`);
5050
const isInvalid = computed(() => Object.keys(props.config).length === 0);
51+
const hasFields = computed(() => Array.isArray(props.config.fields) ? props.config.fields.length > 0 : Object.keys(props.config.fields || {}).length > 0);
5152
5253
const setGroup = computed(() => {
5354
if (replicatorSets.length < 1) return null;
@@ -140,9 +141,9 @@ reveal.use(rootEl, () => emit('expanded'));
140141
:data-type="config.handle"
141142
>
142143
<header
143-
class="group/header animate-border-color flex items-center show-focus-within rounded-[calc(var(--radius-lg)-1px)] px-1.5 antialiased duration-200 bg-gray-100/50 dark:bg-gray-925 hover:bg-gray-100 dark:hover:bg-gray-950/45 border-gray-300 dark:shadow-md border-b-1 border-b-transparent"
144+
class="group/header animate-border-color flex items-center show-focus-within rounded-[calc(var(--radius-lg)-1px)] px-1.5 antialiased duration-200 bg-gray-100/50 dark:bg-gray-925 hover:bg-gray-100 dark:hover:bg-gray-950/45 border-gray-300 dark:shadow-md"
144145
:class="{
145-
'bg-gray-200/50 dark:bg-gray-950/35 rounded-b-none border-b-gray-300! dark:border-b-white/10!': !collapsed
146+
'bg-gray-200/50 dark:bg-gray-950/35 rounded-b-none': !collapsed && hasFields
146147
}"
147148
>
148149
<Icon
@@ -201,7 +202,11 @@ reveal.use(rootEl, () => emit('expanded'));
201202
</div>
202203
</header>
203204
204-
<div v-show="!collapsed" :class="{ 'contain-paint': collapsed, 'isolate': !collapsed }">
205+
<div
206+
v-show="!collapsed && hasFields"
207+
:class="{ 'contain-paint': collapsed, 'isolate': !collapsed }"
208+
class="border-t border-t-gray-300! dark:border-t-white/10!"
209+
>
205210
<div :tabindex="collapsed ? -1 : undefined" :inert="collapsed">
206211
<FieldsProvider
207212
:fields="config.fields"

resources/js/components/fieldtypes/replicator/SetPicker.vue

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
class="xl:max-w-3xl 2xl:max-w-page"
1515
>
1616
<template #trigger>
17-
<slot name="trigger" />
17+
<Primitive @click.capture="onTriggerClick">
18+
<slot name="trigger" />
19+
</Primitive>
1820
</template>
1921

2022
<template #default>
@@ -90,7 +92,9 @@
9092
inset
9193
>
9294
<template #trigger>
93-
<slot name="trigger" />
95+
<Primitive @click.capture="onTriggerClick">
96+
<slot name="trigger" />
97+
</Primitive>
9498
</template>
9599

96100
<template #default>
@@ -449,6 +453,13 @@ export default {
449453
this.isOpen = true;
450454
},
451455
456+
onTriggerClick(e) {
457+
if (!this.enabled) {
458+
e.stopPropagation();
459+
e.preventDefault();
460+
}
461+
},
462+
452463
getStoredMode() {
453464
try {
454465
return localStorage.getItem('statamic.replicator.setPicker.mode') || 'list';

src/Facades/Endpoint/URL.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ public function isExternalToApplication(?string $url): bool
274274
->filter(fn ($siteUrl) => $urlDomain === $siteUrl)
275275
->isEmpty();
276276

277-
$isExternalToCurrentRequestDomain = ! Str::startsWith($url, self::getDomainFromAbsolute(url()->to('/')));
277+
$isExternalToCurrentRequestDomain = $urlDomain !== self::getDomainFromAbsolute(url()->to('/'));
278278

279279
return self::$externalAppUrlsCache[$url] = $isExternalToSites && $isExternalToCurrentRequestDomain;
280280
}
@@ -386,7 +386,7 @@ private function getAbsoluteSiteUrls(): Collection
386386
*/
387387
private function getDomainFromAbsolute(string $url): string
388388
{
389-
return preg_replace('/(https*:\/\/[^\/]+)(.*)/', '$1', $url);
389+
return parse_url($url, PHP_URL_HOST) ?? $url;
390390
}
391391

392392
/**

tests/Facades/Concerns/ProvidesExternalUrls.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,21 @@ public static function externalUrlProvider()
6767
['http://subdomain.this-site.com.au/some-slug', true],
6868
['http://subdomain.this-site.com.au/some-slug?foo', true],
6969
['http://subdomain.this-site.com.au/some-slug#anchor', true],
70+
71+
// Credential injection
72+
['http://this-site.com@evil.com', true],
73+
['http://this-site.com@evil.com/', true],
74+
['http://this-site.com@evil.com/path', true],
75+
['http://this-site.com@evil.com/path?query', true],
76+
['http://this-site.com:password@evil.com', true],
77+
['http://user:pass@evil.com', true],
78+
['http://absolute-url-resolved-from-request.com@evil.com', true],
79+
['http://absolute-url-resolved-from-request.com@evil.com/path', true],
80+
['http://subdomain.this-site.com@evil.com', true],
81+
['http://subdomain.this-site.com@evil.com/path', true],
82+
['http://this-site.com:8000@evil.com', true],
83+
['http://this-site.com:8000@evil.com/path', true],
84+
['http://this-site.com:8000@webhook.site/token', true],
7085
];
7186
}
7287
}

0 commit comments

Comments
 (0)