remove_client.mjs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import minimist from 'minimist'
  2. import {
  3. db,
  4. READ_PREFERENCE_SECONDARY,
  5. } from '../../app/src/infrastructure/mongodb.js'
  6. async function main() {
  7. const opts = parseArgs()
  8. const application = await getApplication(opts.clientId)
  9. if (application == null) {
  10. console.error(`Client configuration not found: ${opts.clientId}`)
  11. process.exit(1)
  12. }
  13. if (opts.commit) {
  14. console.log(
  15. `Preparing to remove OAuth client configuration: ${application.name}.`
  16. )
  17. const deletedAccessTokens = await deleteAccessTokens(application._id)
  18. console.log(`Deleted ${deletedAccessTokens} access tokens`)
  19. const deletedAuthorizationCodes = await deleteAuthorizationCodes(
  20. application._id
  21. )
  22. console.log(`Deleted ${deletedAuthorizationCodes} authorization codes`)
  23. await deleteApplication(application._id)
  24. console.log('Deleted OAuth client configuration')
  25. } else {
  26. console.log(
  27. `Preparing to remove OAuth client configuration (dry run): ${application.name}.`
  28. )
  29. const accessTokenCount = await countAccessTokens(application._id)
  30. const authorizationCodeCount = await countAuthorizationCodes(
  31. application._id
  32. )
  33. console.log(
  34. `This would delete ${accessTokenCount} access tokens and ${authorizationCodeCount} authorization codes.`
  35. )
  36. console.log('This was a dry run. Rerun with --commit to proceed.')
  37. }
  38. }
  39. async function getApplication(clientId) {
  40. return await db.oauthApplications.findOne({ id: clientId })
  41. }
  42. async function countAccessTokens(applicationId) {
  43. return await db.oauthAccessTokens.count(
  44. {
  45. oauthApplication_id: applicationId,
  46. },
  47. { readPreference: READ_PREFERENCE_SECONDARY }
  48. )
  49. }
  50. async function countAuthorizationCodes(applicationId) {
  51. return await db.oauthAuthorizationCodes.count(
  52. {
  53. oauthApplication_id: applicationId,
  54. },
  55. { readPreference: READ_PREFERENCE_SECONDARY }
  56. )
  57. }
  58. async function deleteAccessTokens(applicationId) {
  59. const res = await db.oauthAccessTokens.deleteMany({
  60. oauthApplication_id: applicationId,
  61. })
  62. return res.deletedCount
  63. }
  64. async function deleteAuthorizationCodes(applicationId) {
  65. const res = await db.oauthAuthorizationCodes.deleteMany({
  66. oauthApplication_id: applicationId,
  67. })
  68. return res.deletedCount
  69. }
  70. async function deleteApplication(applicationId) {
  71. await db.oauthApplications.deleteOne({ _id: applicationId })
  72. }
  73. function parseArgs() {
  74. const args = minimist(process.argv.slice(2), {
  75. boolean: ['help', 'commit'],
  76. })
  77. if (args.help) {
  78. usage()
  79. process.exit(0)
  80. }
  81. if (args._.length !== 1) {
  82. usage()
  83. process.exit(1)
  84. }
  85. return {
  86. clientId: args._[0],
  87. commit: args.commit,
  88. }
  89. }
  90. function usage() {
  91. console.error(`Usage: remove_client.js [OPTS...] CLIENT_ID
  92. Removes an OAuth client configuration and all associated tokens and
  93. authorization codes
  94. Options:
  95. --commit Really delete the OAuth application (will do a dry run by default)
  96. `)
  97. }
  98. try {
  99. await main()
  100. process.exit(0)
  101. } catch (error) {
  102. console.error(error)
  103. process.exit(1)
  104. }