messenger.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. const log = require('../../../util/log')
  2. // Derive filenames based on domain + file path
  3. const fileHash = require('../../../util/backup_filehash')
  4. const domain = 'AppDomainGroup-group.com.facebook.Messenger'
  5. module.exports.name = 'facebook_messenger_friends'
  6. module.exports.description = 'Show Facebook Messenger friends'
  7. // Specify this only works for iOS 9+
  8. module.exports.supportedVersions = '>=10.0'
  9. // Specify this reporter requires a backup.
  10. // The second parameter to func() is now a backup instead of the path to one.
  11. module.exports.requiresBackup = true
  12. // Specify this reporter supports the promises API for allowing chaining of reports.
  13. module.exports.usesPromises = true
  14. // You can also provide an array of functions instead of using `module.exports.func`.
  15. // These functions *should* be independent ranges to ensure reliable execution
  16. module.exports.functions = {
  17. '>=10.0': function (program, backup, resolve, reject) {
  18. // This function would be called for iOS 10+
  19. backup.getFileManifest()
  20. .then((items) => {
  21. let filename = 'fbomnistore.db'
  22. let fileitem = items.find((file) => {
  23. if (file && file.relativePath) { return ~file.relativePath.indexOf(filename) }
  24. return false
  25. })
  26. if (fileitem) {
  27. let filepath = fileitem.relativePath
  28. let file = fileHash(filepath, domain)
  29. return facebookMessengerFriendsReport(backup, file)
  30. } else return [] // Return an empty array to the formatter, since no fbomnistore.db file can be found in the manifest
  31. })
  32. .then((items) => {
  33. var result = program.formatter.format(items, {
  34. program: program,
  35. columns: {
  36. 'Facebook Friend Usernames': el => el.field_value
  37. }
  38. })
  39. resolve(result)
  40. })
  41. .catch((e) => {
  42. log.error('[!] Encountered an Error:', e)
  43. })
  44. },
  45. '>=5.0,<10.0': function (program, backup, resolve, reject) {
  46. // This function would be called for all iOS 5 up to iOS 9.x.
  47. // TODO
  48. /* backup.getOldFileManifest()
  49. .then((items) => {
  50. var result = program.formatter.format(items, {
  51. program: program,
  52. columns: {
  53. 'Facebook Friend Username': el => el.field_value
  54. }
  55. })
  56. resolve(result)
  57. })
  58. .catch(reject) */
  59. }
  60. }
  61. const facebookMessengerFriendsReport = (backup, file) => {
  62. return new Promise((resolve, reject) => {
  63. var database = backup.getDatabase(file)
  64. try {
  65. database.get(`
  66. SELECT name
  67. FROM sqlite_master
  68. WHERE type='table'
  69. AND name LIKE 'collection_index#messenger_contacts_ios%'
  70. LIMIT 1
  71. `,
  72. (err, tableName) => {
  73. if (err) return reject(err)
  74. tableName = tableName.name
  75. log.verbose('Table', tableName)
  76. database.all(`
  77. SELECT field_value
  78. FROM '${tableName}'
  79. WHERE field_name='username'
  80. `, (err, rows) => {
  81. if (err) return reject(err)
  82. resolve(rows)
  83. })
  84. })
  85. } catch (e) {
  86. reject(e)
  87. }
  88. })
  89. }