mirror of
https://github.com/selfxyz/self.git
synced 2026-04-05 03:00:53 -04:00
SELF-253 feat: add user email feedback (#889)
* feat: add sentry feedback * add sentry feedback to web * feat: add custom feedback modal & fix freeze on IOS * yarn nice * update lock * feat: show feedback widget on NFC scan issues (#948) * feat: show feedback widget on NFC scan issues * fix ref * clean up * fix report issue screen * abstract send user feedback email logic * fixes * change text to Report Issue * sanitize email and track event messge * remove unnecessary sanitization * add sanitize error message tests * fix tests * save wip. almost done * fix screen test * fix screen test * remove non working test --------- Co-authored-by: Justin Hernandez <transphorm@gmail.com> Co-authored-by: Justin Hernandez <justin.hernandez@self.xyz>
This commit is contained in:
55
app/src/utils/email.ts
Normal file
55
app/src/utils/email.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: BUSL-1.1; Copyright (c) 2025 Social Connect Labs, Inc.; Licensed under BUSL-1.1 (see LICENSE); Apache-2.0 from 2029-06-11
|
||||
|
||||
import { Linking, Platform } from 'react-native';
|
||||
import { getCountry, getLocales, getTimeZone } from 'react-native-localize';
|
||||
|
||||
import { sanitizeErrorMessage } from '@/utils/utils';
|
||||
|
||||
import { version } from '../../package.json';
|
||||
|
||||
interface SendFeedbackEmailOptions {
|
||||
message: string;
|
||||
origin: string;
|
||||
subject?: string;
|
||||
recipient?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a feedback email with device information and user message
|
||||
* @param options Configuration for the feedback email
|
||||
*/
|
||||
export const sendFeedbackEmail = async ({
|
||||
message,
|
||||
origin,
|
||||
subject = 'SELF App Feedback',
|
||||
recipient = 'team@self.xyz',
|
||||
}: SendFeedbackEmailOptions): Promise<void> => {
|
||||
const deviceInfo = [
|
||||
['device', `${Platform.OS}@${Platform.Version}`],
|
||||
['app', `v${version}`],
|
||||
[
|
||||
'locales',
|
||||
getLocales()
|
||||
.map(locale => `${locale.languageCode}-${locale.countryCode}`)
|
||||
.join(','),
|
||||
],
|
||||
['country', getCountry()],
|
||||
['tz', getTimeZone()],
|
||||
['ts', new Date().toISOString()],
|
||||
['origin', origin],
|
||||
['error', sanitizeErrorMessage(message)],
|
||||
] as [string, string][];
|
||||
|
||||
const body = `Please describe the issue you're experiencing:
|
||||
|
||||
---
|
||||
Technical Details (do not modify):
|
||||
${deviceInfo.map(([k, v]) => `${k}=${v}`).join('\n')}
|
||||
---`;
|
||||
|
||||
await Linking.openURL(
|
||||
`mailto:${recipient}?subject=${encodeURIComponent(
|
||||
subject,
|
||||
)}&body=${encodeURIComponent(body)}`,
|
||||
);
|
||||
};
|
||||
@@ -16,3 +16,14 @@ export function checkScannedInfo(
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Redacts 9+ consecutive digits and MRZ-like blocks to reduce PII exposure
|
||||
export const sanitizeErrorMessage = (msg: string): string => {
|
||||
try {
|
||||
return msg
|
||||
.replace(/\b\d{9,}\b/g, '[REDACTED]')
|
||||
.replace(/[A-Z0-9<]{30,}/g, '[MRZ_REDACTED]');
|
||||
} catch {
|
||||
return 'redacted';
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user