mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 14:35:41 +00:00
fix(settings): remove plaintext password reveal from server/user forms (#837)
This commit is contained in:
committed by
GitHub
parent
cb9445eaad
commit
f9f96f024f
@@ -1,6 +1,5 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Eye, EyeOff } from 'lucide-react';
|
|
||||||
import type { ServerProfile } from '../../store/authStoreTypes';
|
import type { ServerProfile } from '../../store/authStoreTypes';
|
||||||
import { showToast } from '../../utils/ui/toast';
|
import { showToast } from '../../utils/ui/toast';
|
||||||
import {
|
import {
|
||||||
@@ -30,12 +29,10 @@ export function AddServerForm({
|
|||||||
: { name: '', url: '', username: '', password: '' },
|
: { name: '', url: '', username: '', password: '' },
|
||||||
);
|
);
|
||||||
const [magicString, setMagicString] = useState('');
|
const [magicString, setMagicString] = useState('');
|
||||||
const [showPass, setShowPass] = useState(false);
|
|
||||||
const [blockPasswordReveal, setBlockPasswordReveal] = useState(false);
|
const [blockPasswordReveal, setBlockPasswordReveal] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!initialInvite) return;
|
if (!initialInvite) return;
|
||||||
setShowPass(false);
|
|
||||||
setBlockPasswordReveal(true);
|
setBlockPasswordReveal(true);
|
||||||
setForm({
|
setForm({
|
||||||
name: (initialInvite.name && initialInvite.name.trim()) || shortHostFromServerUrl(initialInvite.url),
|
name: (initialInvite.name && initialInvite.name.trim()) || shortHostFromServerUrl(initialInvite.url),
|
||||||
@@ -55,7 +52,6 @@ export function AddServerForm({
|
|||||||
const trimmed = v.trim();
|
const trimmed = v.trim();
|
||||||
const decoded = decodeServerMagicString(trimmed);
|
const decoded = decodeServerMagicString(trimmed);
|
||||||
if (decoded) {
|
if (decoded) {
|
||||||
setShowPass(false);
|
|
||||||
setBlockPasswordReveal(true);
|
setBlockPasswordReveal(true);
|
||||||
setForm({
|
setForm({
|
||||||
name: (decoded.name && decoded.name.trim()) || shortHostFromServerUrl(decoded.url),
|
name: (decoded.name && decoded.name.trim()) || shortHostFromServerUrl(decoded.url),
|
||||||
@@ -135,23 +131,13 @@ export function AddServerForm({
|
|||||||
style={{ letterSpacing: '0.12em', cursor: 'default' }}
|
style={{ letterSpacing: '0.12em', cursor: 'default' }}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div style={{ position: 'relative' }}>
|
|
||||||
<input
|
<input
|
||||||
className="input"
|
className="input"
|
||||||
type={showPass ? 'text' : 'password'}
|
type="password"
|
||||||
value={form.password}
|
value={form.password}
|
||||||
onChange={update('password')}
|
onChange={update('password')}
|
||||||
placeholder="••••••••"
|
placeholder="••••••••"
|
||||||
style={{ paddingRight: '2.5rem' }}
|
|
||||||
/>
|
/>
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
style={{ position: 'absolute', right: '10px', top: '50%', transform: 'translateY(-50%)', color: 'var(--text-muted)' }}
|
|
||||||
onClick={() => setShowPass(v => !v)}
|
|
||||||
>
|
|
||||||
{showPass ? <EyeOff size={14} /> : <Eye size={14} />}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Eye, EyeOff, Shield, Wand2 } from 'lucide-react';
|
import { Shield, Wand2 } from 'lucide-react';
|
||||||
import { ndUpdateUser, type NdLibrary, type NdUser } from '../../api/navidromeAdmin';
|
import { ndUpdateUser, type NdLibrary, type NdUser } from '../../api/navidromeAdmin';
|
||||||
import { showToast } from '../../utils/ui/toast';
|
import { showToast } from '../../utils/ui/toast';
|
||||||
import {
|
import {
|
||||||
@@ -54,7 +54,6 @@ export function UserForm({
|
|||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [form, setForm] = useState<UserFormState>(() => initialUserFormState(initial ?? undefined, libraries));
|
const [form, setForm] = useState<UserFormState>(() => initialUserFormState(initial ?? undefined, libraries));
|
||||||
const [showPass, setShowPass] = useState(false);
|
|
||||||
const [magicGenBusy, setMagicGenBusy] = useState(false);
|
const [magicGenBusy, setMagicGenBusy] = useState(false);
|
||||||
const [showNewUserRequiredErrors, setShowNewUserRequiredErrors] = useState(false);
|
const [showNewUserRequiredErrors, setShowNewUserRequiredErrors] = useState(false);
|
||||||
const isEdit = !!initial;
|
const isEdit = !!initial;
|
||||||
@@ -206,28 +205,16 @@ export function UserForm({
|
|||||||
{t('settings.userMgmtPassword')}
|
{t('settings.userMgmtPassword')}
|
||||||
{!isEdit && <span style={{ color: 'var(--text-muted)' }}> *</span>}
|
{!isEdit && <span style={{ color: 'var(--text-muted)' }}> *</span>}
|
||||||
</label>
|
</label>
|
||||||
<div style={{ position: 'relative' }}>
|
|
||||||
<input
|
<input
|
||||||
className="input"
|
className="input"
|
||||||
type={showPass ? 'text' : 'password'}
|
type="password"
|
||||||
value={form.password}
|
value={form.password}
|
||||||
onChange={e => set('password', e.target.value)}
|
onChange={e => set('password', e.target.value)}
|
||||||
placeholder="••••••••"
|
placeholder="••••••••"
|
||||||
autoComplete="new-password"
|
autoComplete="new-password"
|
||||||
aria-invalid={markInvalid && !form.password.trim()}
|
aria-invalid={markInvalid && !form.password.trim()}
|
||||||
style={{
|
style={markInvalid && !form.password.trim() ? { borderColor: 'var(--danger)' } : undefined}
|
||||||
paddingRight: '2.5rem',
|
|
||||||
...(markInvalid && !form.password.trim() ? { borderColor: 'var(--danger)' } : {}),
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
style={{ position: 'absolute', right: '10px', top: '50%', transform: 'translateY(-50%)', color: 'var(--text-muted)' }}
|
|
||||||
onClick={() => setShowPass(v => !v)}
|
|
||||||
>
|
|
||||||
{showPass ? <EyeOff size={14} /> : <Eye size={14} />}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{isEdit && (
|
{isEdit && (
|
||||||
<div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 4 }}>
|
<div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 4 }}>
|
||||||
{t('settings.userMgmtPasswordEditHint')}
|
{t('settings.userMgmtPasswordEditHint')}
|
||||||
|
|||||||
Reference in New Issue
Block a user