Files
windmill/frontend/src/lib/components/InstanceNameEditor.svelte
T
Ruben Fiszel f9d5da11b7 feat: allow changing an account email in the superadmin settings (#10355)
* feat: allow changing an account email in the superadmin settings

* fix: cover slack_email and usage rows, and scope job rewrites to the queue

* fix: compare the destination email case-insensitively

* fix: only warn about the consequences once the email is edited

* docs: warn that changing an account email is a last resort

* fix: repoint app policies and raw-email permissioned_as, reject self-change

* fix: repoint folder default rules and guard the varchar(55) job column
2026-07-27 14:54:23 +02:00

180 lines
4.4 KiB
Svelte

<script lang="ts">
import { stopPropagation, createBubbler } from 'svelte/legacy'
const bubble = createBubbler()
import { Pencil } from 'lucide-svelte'
import { createEventDispatcher } from 'svelte'
import Button from './common/button/Button.svelte'
import Popover from './meltComponents/Popover.svelte'
import { offset, flip, shift } from 'svelte-floating-ui/dom'
import ChangeInstanceUsernameInner from './ChangeInstanceUsernameInner.svelte'
import ChangeInstanceEmailInner from './ChangeInstanceEmailInner.svelte'
import { UserService } from '$lib/gen'
import { sendUserToast } from '$lib/toast'
import TextInput from './text_input/TextInput.svelte'
interface Props {
value: string | undefined
email: string
username?: string | undefined
automateUsernameCreation?: boolean
login_type: string
}
let {
value = $bindable(),
email,
username = undefined,
automateUsernameCreation = false,
login_type = $bindable()
}: Props = $props()
let password: string = $state('')
const dispatch = createEventDispatcher()
function saveName() {
dispatch('save', value)
}
async function savePassword() {
if (password.length < 5) {
sendUserToast('Password must be at least 5 characters long', true)
return
}
await UserService.setPasswordForUser({ user: email, requestBody: { password } })
sendUserToast(`Password updated for ${email}`)
}
async function saveLoginType() {
await UserService.setLoginTypeForUser({ user: email, requestBody: { login_type } })
sendUserToast(`Login type updated for ${email}`)
dispatch('refresh')
}
</script>
<Popover
floatingConfig={{
strategy: 'fixed',
placement: 'left-end',
middleware: [offset(8), flip(), shift()]
}}
closeButton
>
{#snippet trigger()}
<Button unifiedSize="sm" nonCaptureEvent={true} variant="subtle" startIcon={{ icon: Pencil }}
>Edit</Button
>
{/snippet}
{#snippet content()}
<div class="flex flex-col gap-8 max-w-sm p-4">
<ChangeInstanceEmailInner
{email}
{username}
noPadding
on:changed={() => dispatch('refresh')}
/>
{#if automateUsernameCreation && username}
<ChangeInstanceUsernameInner {email} {username} on:renamed noPadding />
{/if}
<label class="block text-primary">
<div class="pb-1 text-xs font-semibold text-emphasis">Name</div>
<div class="flex w-full">
<TextInput
inputProps={{
onclick: (e) => {
e.stopPropagation()
},
onkeydown: (e) => {
e.stopPropagation()
},
onkeypress: ({ key }) => {
if (key === 'Enter') {
saveName()
}
}
}}
bind:value
/>
</div>
<Button
unifiedSize="md"
variant="default"
buttonType="button"
btnClasses="mt-2 "
aria-label="Save ID"
onclick={() => {
saveName()
}}
>
Update name
</Button>
</label>
<label class="block text-primary">
<div class="pb-1 text-xs font-semibold text-emphasis">Password</div>
<div class="flex w-full">
<input
type="password"
bind:value={password}
class="!w-auto grow"
onclick={stopPropagation(() => {})}
onkeydown={stopPropagation(bubble('keydown'))}
onkeypress={(e) => {
e.stopPropagation()
if (e.key === 'Enter') {
savePassword()
}
}}
/>
</div>
<Button
unifiedSize="md"
variant="default"
buttonType="button"
btnClasses="mt-2 "
aria-label="Save ID"
on:click={() => {
savePassword()
}}
>
Update password
</Button>
</label>
<label class="block text-primary">
<div class="mb-1 text-xs font-semibold text-emphasis">Login type</div>
<div class="flex w-full">
<input
type="text"
bind:value={login_type}
class="!w-auto grow"
onclick={stopPropagation(() => {})}
onkeydown={stopPropagation(bubble('keydown'))}
onkeypress={(e) => {
e.stopPropagation()
if (e.key === 'Enter') {
saveLoginType()
}
}}
/>
</div>
<div class="text-2xs text-secondary mb-1">
Must match exact SSO name, "password" or "saml". Examples: password, google, saml,
microsoft
</div>
<Button
unifiedSize="md"
variant="default"
buttonType="button"
btnClasses="mt-2 "
aria-label="Save login type"
on:click={() => {
saveLoginType()
}}
>
Update login type
</Button>
</label>
</div>
{/snippet}
</Popover>