register_client.mjs 3.5 KB

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