mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-11 08:07:15 +00:00
* 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
180 lines
4.4 KiB
Svelte
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>
|