feat(user): enhance email handling with validation and normalization functions
All checks were successful
Deploy to production / deploy (push) Successful in 2m56s
All checks were successful
Deploy to production / deploy (push) Successful in 2m56s
- Introduced `looksLikePlausibleEmail` to validate email format, ensuring only plausible addresses are processed. - Added `normalizeEmailCandidate` to standardize email input, returning null for invalid formats. - Updated `decodeEncryptedBlob` to utilize normalization functions for both UTF-8 and hex formats, improving email decryption reliability. - Adjusted `SettingsService` to ensure email is set after merging adult access state, maintaining data integrity.
This commit is contained in:
@@ -8,6 +8,26 @@ function encodeEncryptedValueToBlob(value) {
|
|||||||
return Buffer.from(encrypted, 'utf8');
|
return Buffer.from(encrypted, 'utf8');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Nur echte Adressen zurückgeben — verhindert Anzeige von Base64-/Key-artigem Müll bei fehlender Entschlüsselung. */
|
||||||
|
function looksLikePlausibleEmail(s) {
|
||||||
|
if (typeof s !== 'string') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const t = s.trim();
|
||||||
|
if (!t || t.length > 254) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i.test(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeEmailCandidate(s) {
|
||||||
|
if (!s || typeof s !== 'string') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const t = s.trim();
|
||||||
|
return looksLikePlausibleEmail(t) ? t : null;
|
||||||
|
}
|
||||||
|
|
||||||
function decodeEncryptedBlob(value) {
|
function decodeEncryptedBlob(value) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return null;
|
return null;
|
||||||
@@ -16,8 +36,9 @@ function decodeEncryptedBlob(value) {
|
|||||||
try {
|
try {
|
||||||
const encryptedUtf8 = value.toString('utf8');
|
const encryptedUtf8 = value.toString('utf8');
|
||||||
const decryptedUtf8 = decrypt(encryptedUtf8);
|
const decryptedUtf8 = decrypt(encryptedUtf8);
|
||||||
if (decryptedUtf8) {
|
const fromUtf8 = normalizeEmailCandidate(decryptedUtf8);
|
||||||
return decryptedUtf8;
|
if (fromUtf8) {
|
||||||
|
return fromUtf8;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Email utf8 decryption failed, trying legacy hex format:', error.message);
|
console.warn('Email utf8 decryption failed, trying legacy hex format:', error.message);
|
||||||
@@ -26,15 +47,16 @@ function decodeEncryptedBlob(value) {
|
|||||||
try {
|
try {
|
||||||
const encryptedHex = value.toString('hex');
|
const encryptedHex = value.toString('hex');
|
||||||
const decryptedHex = decrypt(encryptedHex);
|
const decryptedHex = decrypt(encryptedHex);
|
||||||
if (decryptedHex) {
|
const fromHex = normalizeEmailCandidate(decryptedHex);
|
||||||
return decryptedHex;
|
if (fromHex) {
|
||||||
|
return fromHex;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Email legacy hex decryption failed:', error.message);
|
console.warn('Email legacy hex decryption failed:', error.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return value.toString('utf8');
|
return normalizeEmailCandidate(value.toString('utf8'));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Email could not be read as plain text:', error.message);
|
console.warn('Email could not be read as plain text:', error.message);
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -426,11 +426,12 @@ class SettingsService extends BaseService{
|
|||||||
|
|
||||||
const adultAccess = await this.getAdultAccessStateByUserId(user.id);
|
const adultAccess = await this.getAdultAccessStateByUserId(user.id);
|
||||||
|
|
||||||
|
/* adultAccess zuletzt mergen, email danach setzen — nie von anderen Payload-Feldern überschreiben */
|
||||||
return {
|
return {
|
||||||
username: user.username,
|
username: user.username,
|
||||||
email: email,
|
|
||||||
showinsearch: user.searchable,
|
showinsearch: user.searchable,
|
||||||
...adultAccess
|
...adultAccess,
|
||||||
|
email,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error getting account settings:', error);
|
console.error('Error getting account settings:', error);
|
||||||
|
|||||||
Reference in New Issue
Block a user