count_encrypted_access_tokens.js 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. const TEN_MINUTES = 1000 * 60 * 10
  2. process.env.MONGO_SOCKET_TIMEOUT =
  3. process.env.MONGO_SOCKET_TIMEOUT || TEN_MINUTES.toString()
  4. const { ReadPreference } = require('mongodb')
  5. const { db, waitForDb } = require('../app/src/infrastructure/mongodb')
  6. const _ = require('lodash')
  7. const CASES = {
  8. users: {
  9. dropbox: 'dropbox.access_token_oauth2.encrypted',
  10. zotero: 'refProviders.zotero.encrypted',
  11. mendeley: 'refProviders.mendeley.encrypted',
  12. },
  13. githubSyncUserCredentials: {
  14. github: 'auth_token_encrypted',
  15. },
  16. }
  17. async function count(collectionName, paths) {
  18. const collection = db[collectionName]
  19. const stats = {}
  20. const projection = { _id: 0 }
  21. for (const path of Object.values(paths)) {
  22. projection[path] = 1
  23. }
  24. const cursor = collection.find(
  25. {},
  26. {
  27. readPreference: ReadPreference.SECONDARY,
  28. projection,
  29. }
  30. )
  31. for await (const doc of cursor) {
  32. for (const [name, path] of Object.entries(paths)) {
  33. const blob = _.get(doc, path)
  34. if (!blob) continue
  35. // Schema: LABEL:SALT:CIPHERTEXT:IV
  36. const [label, , , iv] = blob.split(':', 4)
  37. const version = iv ? 'v2' : 'v1'
  38. const key = [name, version, collectionName, path, label].join(':')
  39. stats[key] = (stats[key] || 0) + 1
  40. }
  41. }
  42. return stats
  43. }
  44. async function main() {
  45. await waitForDb()
  46. const STATS = {}
  47. for (const [collectionName, paths] of Object.entries(CASES)) {
  48. const stats = await count(collectionName, paths)
  49. Object.assign(STATS, stats)
  50. }
  51. const prettyStats = []
  52. const sortedStats = Object.entries(STATS).sort((a, b) =>
  53. a[0] > b[0] ? 1 : -1
  54. )
  55. const totalByName = {}
  56. for (const [key, n] of sortedStats) {
  57. const [name, version, collectionName, path, label] = key.split(':')
  58. totalByName[name] = (totalByName[name] || 0) + n
  59. prettyStats.push({ name, version, collectionName, path, label, n })
  60. }
  61. for (const row of prettyStats) {
  62. row.percentage = ((100 * row.n) / totalByName[row.name])
  63. .toFixed(2)
  64. .padStart(6)
  65. }
  66. console.table(prettyStats)
  67. }
  68. main()
  69. .then(() => {
  70. process.exit(0)
  71. })
  72. .catch(err => {
  73. console.error(err)
  74. process.exit(1)
  75. })