register_client.mjs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import minimist from 'minimist'
  2. import mongodb from 'mongodb-legacy'
  3. import { db } from '../../app/src/infrastructure/mongodb.js'
  4. import { hashSecret } from '../../modules/oauth2-server/app/src/SecretsHelper.js'
  5. const { ObjectId } = mongodb
  6. async function main() {
  7. const opts = parseArgs()
  8. const application = await getApplication(opts.id)
  9. if (application == null) {
  10. console.log(
  11. `Application ${opts.id} is not registered. Creating a new configuration.`
  12. )
  13. if (opts.name == null) {
  14. console.error('Missing --name option')
  15. process.exit(1)
  16. }
  17. } else {
  18. console.log(`Updating configuration for client: ${application.name}`)
  19. if (opts.mongoId != null) {
  20. console.error('Cannot change Mongo ID for an existing client')
  21. process.exit(1)
  22. }
  23. }
  24. await upsertApplication(opts)
  25. }
  26. async function getApplication(clientId) {
  27. return await db.oauthApplications.findOne({ id: clientId })
  28. }
  29. async function upsertApplication(opts) {
  30. const key = { id: opts.id }
  31. const defaults = {}
  32. const updates = {}
  33. if (opts.name != null) {
  34. updates.name = opts.name
  35. }
  36. if (opts.secret != null) {
  37. updates.clientSecret = hashSecret(opts.secret)
  38. }
  39. if (opts.grants != null) {
  40. updates.grants = opts.grants
  41. } else {
  42. defaults.grants = []
  43. }
  44. if (opts.scopes != null) {
  45. updates.scopes = opts.scopes
  46. } else {
  47. defaults.scopes = []
  48. }
  49. if (opts.redirectUris != null) {
  50. updates.redirectUris = opts.redirectUris
  51. } else {
  52. defaults.redirectUris = []
  53. }
  54. if (opts.mongoId != null) {
  55. defaults._id = new ObjectId(opts.mongoId)
  56. }
  57. if (opts.enablePkce) {
  58. updates.pkceEnabled = true
  59. }
  60. if (opts.disablePkce) {
  61. updates.pkceEnabled = false
  62. }
  63. await db.oauthApplications.updateOne(
  64. key,
  65. {
  66. $setOnInsert: { ...key, ...defaults },
  67. $set: updates,
  68. },
  69. { upsert: true }
  70. )
  71. }
  72. function parseArgs() {
  73. const args = minimist(process.argv.slice(2), {
  74. boolean: ['help', 'enable-pkce', 'disable-pkce'],
  75. })
  76. if (args.help) {
  77. usage()
  78. process.exit(0)
  79. }
  80. if (args._.length !== 1) {
  81. usage()
  82. process.exit(1)
  83. }
  84. if (args['enable-pkce'] && args['disable-pkce']) {
  85. console.error('Options --enable-pkce and --disable-pkce are exclusive')
  86. process.exit(1)
  87. }
  88. return {
  89. id: args._[0],
  90. mongoId: args['mongo-id'],
  91. name: args.name,
  92. secret: args.secret,
  93. scopes: toArray(args.scope),
  94. grants: toArray(args.grant),
  95. redirectUris: toArray(args['redirect-uri']),
  96. enablePkce: args['enable-pkce'],
  97. disablePkce: args['disable-pkce'],
  98. }
  99. }
  100. function usage() {
  101. console.error(`Usage: register_client.js [OPTS...] CLIENT_ID
  102. Creates or updates an OAuth client configuration
  103. Options:
  104. --name Descriptive name for the OAuth client (required for creation)
  105. --secret Client secret
  106. --scope Accepted scope (can be given more than once)
  107. --grant Accepted grant type (can be given more than once)
  108. --redirect-uri Accepted redirect URI (can be given more than once)
  109. --mongo-id Mongo ID to use if the configuration is created (optional)
  110. --enable-pkce Enable PKCE
  111. --disable-pkce Disable PKCE
  112. `)
  113. }
  114. function toArray(value) {
  115. if (value != null && !Array.isArray(value)) {
  116. return [value]
  117. } else {
  118. return value
  119. }
  120. }
  121. try {
  122. await main()
  123. process.exit(0)
  124. } catch (error) {
  125. console.error(error)
  126. process.exit(1)
  127. }