fix: clear identity signature fields when emptied
This commit is contained in:
@@ -36,10 +36,10 @@ function truncateToUtf8Bytes(s: string, maxBytes: number): string {
|
|||||||
interface IdentityFormData {
|
interface IdentityFormData {
|
||||||
name: string;
|
name: string;
|
||||||
email: string;
|
email: string;
|
||||||
replyTo?: EmailAddress[];
|
replyTo?: EmailAddress[] | null;
|
||||||
bcc?: EmailAddress[];
|
bcc?: EmailAddress[] | null;
|
||||||
textSignature?: string;
|
textSignature?: string | null;
|
||||||
htmlSignature?: string;
|
htmlSignature?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IdentityFormProps {
|
interface IdentityFormProps {
|
||||||
@@ -121,14 +121,16 @@ export function IdentityForm({ identity, onSave, onCancel }: IdentityFormProps)
|
|||||||
setIsSubmitting(true);
|
setIsSubmitting(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Sanitize HTML signature before sending to server
|
// JMAP needs explicit null to clear a field; undefined would be dropped
|
||||||
|
// from the JSON payload and leave the server-side value untouched.
|
||||||
|
const trimmedText = formData.textSignature?.trim() ?? '';
|
||||||
|
const trimmedHtml = formData.htmlSignature?.trim() ?? '';
|
||||||
const sanitizedData: IdentityFormData = {
|
const sanitizedData: IdentityFormData = {
|
||||||
...formData,
|
...formData,
|
||||||
replyTo: parseEmailList(replyToInput),
|
textSignature: trimmedText ? formData.textSignature : null,
|
||||||
bcc: parseEmailList(bccInput),
|
htmlSignature: trimmedHtml ? sanitizeSignatureHtml(formData.htmlSignature!) : null,
|
||||||
htmlSignature: formData.htmlSignature
|
replyTo: parseEmailList(replyToInput) ?? null,
|
||||||
? sanitizeSignatureHtml(formData.htmlSignature)
|
bcc: parseEmailList(bccInput) ?? null,
|
||||||
: undefined,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
await onSave(sanitizedData);
|
await onSave(sanitizedData);
|
||||||
@@ -271,7 +273,7 @@ export function IdentityForm({ identity, onSave, onCancel }: IdentityFormProps)
|
|||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
id="identity-text-sig"
|
id="identity-text-sig"
|
||||||
value={formData.textSignature}
|
value={formData.textSignature ?? ''}
|
||||||
onChange={(e) => setFormData({ ...formData, textSignature: truncateToUtf8Bytes(e.target.value, SIGNATURE_MAX_BYTES) })}
|
onChange={(e) => setFormData({ ...formData, textSignature: truncateToUtf8Bytes(e.target.value, SIGNATURE_MAX_BYTES) })}
|
||||||
rows={3}
|
rows={3}
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
@@ -289,7 +291,7 @@ export function IdentityForm({ identity, onSave, onCancel }: IdentityFormProps)
|
|||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
id="identity-html-sig"
|
id="identity-html-sig"
|
||||||
value={formData.htmlSignature}
|
value={formData.htmlSignature ?? ''}
|
||||||
onChange={(e) => setFormData({ ...formData, htmlSignature: truncateToUtf8Bytes(e.target.value, SIGNATURE_MAX_BYTES) })}
|
onChange={(e) => setFormData({ ...formData, htmlSignature: truncateToUtf8Bytes(e.target.value, SIGNATURE_MAX_BYTES) })}
|
||||||
rows={5}
|
rows={5}
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ function emailMatchesUsername(email: string, username: string): boolean {
|
|||||||
interface IdentityFormData {
|
interface IdentityFormData {
|
||||||
name: string;
|
name: string;
|
||||||
email: string;
|
email: string;
|
||||||
replyTo?: EmailAddress[];
|
replyTo?: EmailAddress[] | null;
|
||||||
bcc?: EmailAddress[];
|
bcc?: EmailAddress[] | null;
|
||||||
textSignature?: string;
|
textSignature?: string | null;
|
||||||
htmlSignature?: string;
|
htmlSignature?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IdentityManagerModalProps {
|
interface IdentityManagerModalProps {
|
||||||
|
|||||||
@@ -530,7 +530,7 @@ export class DemoJMAPClient implements IJMAPClient {
|
|||||||
async createIdentity(
|
async createIdentity(
|
||||||
name: string, email: string,
|
name: string, email: string,
|
||||||
replyTo?: EmailAddress[] | null, bcc?: EmailAddress[] | null,
|
replyTo?: EmailAddress[] | null, bcc?: EmailAddress[] | null,
|
||||||
htmlSignature?: string, textSignature?: string,
|
textSignature?: string | null, htmlSignature?: string | null,
|
||||||
): Promise<Identity> {
|
): Promise<Identity> {
|
||||||
const identity: Identity = {
|
const identity: Identity = {
|
||||||
id: generateDemoId('identity'), name, email,
|
id: generateDemoId('identity'), name, email,
|
||||||
@@ -542,9 +542,14 @@ export class DemoJMAPClient implements IJMAPClient {
|
|||||||
return identity;
|
return identity;
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateIdentity(identityId: string, updates: { name?: string; replyTo?: EmailAddress[] | null; bcc?: EmailAddress[] | null; htmlSignature?: string; textSignature?: string }): Promise<void> {
|
async updateIdentity(identityId: string, updates: { name?: string | null; replyTo?: EmailAddress[] | null; bcc?: EmailAddress[] | null; textSignature?: string | null; htmlSignature?: string | null }): Promise<void> {
|
||||||
const identity = this.data.identities.find(i => i.id === identityId);
|
const identity = this.data.identities.find(i => i.id === identityId);
|
||||||
if (identity) Object.assign(identity, updates);
|
if (!identity) return;
|
||||||
|
if (updates.name !== undefined) identity.name = updates.name ?? '';
|
||||||
|
if (updates.replyTo !== undefined) identity.replyTo = updates.replyTo ?? undefined;
|
||||||
|
if (updates.bcc !== undefined) identity.bcc = updates.bcc ?? undefined;
|
||||||
|
if (updates.textSignature !== undefined) identity.textSignature = updates.textSignature ?? '';
|
||||||
|
if (updates.htmlSignature !== undefined) identity.htmlSignature = updates.htmlSignature ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteIdentity(identityId: string): Promise<void> {
|
async deleteIdentity(identityId: string): Promise<void> {
|
||||||
|
|||||||
@@ -183,17 +183,17 @@ export interface IJMAPClient {
|
|||||||
email: string,
|
email: string,
|
||||||
replyTo?: EmailAddress[] | null,
|
replyTo?: EmailAddress[] | null,
|
||||||
bcc?: EmailAddress[] | null,
|
bcc?: EmailAddress[] | null,
|
||||||
htmlSignature?: string,
|
textSignature?: string | null,
|
||||||
textSignature?: string,
|
htmlSignature?: string | null,
|
||||||
): Promise<Identity>;
|
): Promise<Identity>;
|
||||||
updateIdentity(
|
updateIdentity(
|
||||||
identityId: string,
|
identityId: string,
|
||||||
updates: {
|
updates: {
|
||||||
name?: string;
|
name?: string | null;
|
||||||
replyTo?: EmailAddress[] | null;
|
replyTo?: EmailAddress[] | null;
|
||||||
bcc?: EmailAddress[] | null;
|
bcc?: EmailAddress[] | null;
|
||||||
htmlSignature?: string;
|
textSignature?: string | null;
|
||||||
textSignature?: string;
|
htmlSignature?: string | null;
|
||||||
},
|
},
|
||||||
): Promise<void>;
|
): Promise<void>;
|
||||||
deleteIdentity(identityId: string): Promise<void>;
|
deleteIdentity(identityId: string): Promise<void>;
|
||||||
|
|||||||
+9
-9
@@ -1813,10 +1813,10 @@ export class JMAPClient implements IJMAPClient {
|
|||||||
async createIdentity(
|
async createIdentity(
|
||||||
name: string,
|
name: string,
|
||||||
email: string,
|
email: string,
|
||||||
replyTo?: EmailAddress[],
|
replyTo?: EmailAddress[] | null,
|
||||||
bcc?: EmailAddress[],
|
bcc?: EmailAddress[] | null,
|
||||||
textSignature?: string,
|
textSignature?: string | null,
|
||||||
htmlSignature?: string
|
htmlSignature?: string | null
|
||||||
): Promise<Identity> {
|
): Promise<Identity> {
|
||||||
const response = await this.request([
|
const response = await this.request([
|
||||||
["Identity/set", {
|
["Identity/set", {
|
||||||
@@ -1859,11 +1859,11 @@ export class JMAPClient implements IJMAPClient {
|
|||||||
async updateIdentity(
|
async updateIdentity(
|
||||||
identityId: string,
|
identityId: string,
|
||||||
updates: {
|
updates: {
|
||||||
name?: string;
|
name?: string | null;
|
||||||
replyTo?: EmailAddress[];
|
replyTo?: EmailAddress[] | null;
|
||||||
bcc?: EmailAddress[];
|
bcc?: EmailAddress[] | null;
|
||||||
textSignature?: string;
|
textSignature?: string | null;
|
||||||
htmlSignature?: string;
|
htmlSignature?: string | null;
|
||||||
}
|
}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const response = await this.request([
|
const response = await this.request([
|
||||||
|
|||||||
Reference in New Issue
Block a user