remove_client.mjs 3.1 KB

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