Skip to content

Commit

Permalink
fix: Upload DB files to the Cozy instead of sending them by email
Browse files Browse the repository at this point in the history
In previous commit we implemented a mechanism to send DB files by email
as attachments

This would not work because DB files may be bigger than most common
email providers' size limit

So instead of sending them as attachment, we now upload them in the
Cozy, we create a sharing link and then we send this sharing link by
email

The folder used for the upload is `Settings/AALogs/<datetime>`
s
  • Loading branch information
Ldoppea committed Oct 1, 2024
1 parent 049ea08 commit 4c89679
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 36 deletions.
4 changes: 0 additions & 4 deletions __tests__/jestSetupFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,3 @@ jest.mock('cozy-pouch-link', () => {
jest.mock('react-native-mail', () => ({
mail: jest.fn()
}))

jest.mock('rn-fetch-blob', () => ({
mail: jest.fn()
}))
83 changes: 51 additions & 32 deletions src/pouchdb/sendDbByEmail.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { Alert, PermissionsAndroid, Platform } from 'react-native'
import { format } from 'date-fns'
import { Alert, PermissionsAndroid } from 'react-native'
import Mailer from 'react-native-mail'
import RNFS from 'react-native-fs'
import RNFetchBlob from 'rn-fetch-blob'
import DeviceInfo from 'react-native-device-info'

import type CozyClient from 'cozy-client'
// @ts-expect-error Not typed
import { getSharingLink } from 'cozy-client/dist/models/sharing'
import Minilog from 'cozy-minilog'

import { fetchSupportMail } from '/app/domain/logger/supportEmail'
import { uploadFileWithConflictStrategy } from '/app/domain/upload/services'
import {
hideSplashScreen,
showSplashScreen,
Expand Down Expand Up @@ -42,32 +45,36 @@ export const sendDbByEmail = async (client?: CozyClient): Promise<void> => {

const dbFiles = files.filter(f => f.name.startsWith(`${fqdn}_`))

const externalFiles = []
for (const dbFile of dbFiles) {
const dirs = RNFetchBlob.fs.dirs

const internalPath = dbFile.path
const token = client.getStackClient().token.accessToken

if (Platform.OS === 'android') {
const date = Number(new Date())
const externalPath = `${dirs.DCIMDir}/DbFile_${dbFile.name}${date}.sqlite`
if (!token) {
throw new Error('No token found')
}

await RNFS.copyFile(internalPath, externalPath)
const date = format(new Date(), 'yyyyMMddHHmmssSSS')
const existingLogsFolderId = await client
.collection('io.cozy.files')
.ensureDirectoryExists(`/Settings/AALogs/${date}`)

externalFiles.push({
path: externalPath
})
} else {
externalFiles.push({
path: dbFile.path,
type: 'pdf' // there is no compatible MIME type, so we use PDF one as replacement, this should change nothing expect the email aspect
})
}
for (const dbFile of dbFiles) {
const url = getUrl(client, existingLogsFolderId, dbFile.name)

log.info('Send file', dbFile.name)
await uploadFileWithConflictStrategy({
url,
token,
filename: dbFile.name,
filepath: dbFile.path,
mimetype: '.sqlite'
})
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
const link: string = await getSharingLink(client, [existingLogsFolderId])

await showSplashScreen(splashScreens.SEND_LOG_EMAIL)
log.info('Start email intent', externalFiles)
await sendMailPromise(subject, supportEmail, externalFiles).catch(
log.info('Start email intent')
await sendMailPromise(subject, supportEmail, link).catch(
(errorData: sendMailError) => {
const { error, event } = errorData
Alert.alert(
Expand Down Expand Up @@ -98,16 +105,15 @@ export const sendDbByEmail = async (client?: CozyClient): Promise<void> => {
const sendMailPromise = (
subject: string,
email: string,
attachments: Attachment[]
link: string
): Promise<void> => {
return new Promise((resolve, reject) => {
Mailer.mail(
{
subject: subject,
recipients: [email],
body: buildMessageBody(),
isHTML: true,
attachments: attachments
body: buildMessageBody(link),
isHTML: true
},
(error, event) => {
if (error) {
Expand All @@ -120,7 +126,7 @@ const sendMailPromise = (
})
}

const buildMessageBody = (): string => {
const buildMessageBody = (link: string): string => {
const appVersion = DeviceInfo.getVersion()
const appBuild = DeviceInfo.getBuildNumber()
const bundle = DeviceInfo.getBundleId()
Expand All @@ -129,18 +135,31 @@ const buildMessageBody = (): string => {
const os = DeviceInfo.getSystemName()
const version = DeviceInfo.getSystemVersion()

const linkText = `Link: ${link}`
const appInfo = `App info: ${appVersion} (${appBuild})`
const bundleInfo = `App bundle: ${bundle}`
const deviceInfo = `Device info: ${deviceBrand} ${deviceModel} ${os} ${version}`

return `${appInfo}\n${bundleInfo}\n${deviceInfo}`
return `${linkText}${appInfo}\n${bundleInfo}\n${deviceInfo}`
}

const getUrl = (client: CozyClient, dirId: string, name: string): string => {
const createdAt = new Date().toISOString()
const modifiedAt = new Date().toISOString()

const toURL = new URL(client.getStackClient().uri)
toURL.pathname = `/files/${dirId}`
toURL.searchParams.append('Name', name)
toURL.searchParams.append('Type', 'file')
toURL.searchParams.append('Tags', 'library')
toURL.searchParams.append('Executable', 'false')
toURL.searchParams.append('CreatedAt', createdAt)
toURL.searchParams.append('UpdatedAt', modifiedAt)

return toURL.toString()
}

interface sendMailError {
error: string
event?: string
}

interface Attachment {
path: string
}

0 comments on commit 4c89679

Please sign in to comment.