@open-xchange/soap-client 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env.default CHANGED
@@ -14,3 +14,5 @@ DEBUG_SOAP=false
14
14
  MX_DOMAIN=box.ox.io
15
15
 
16
16
  PROVSIONING_API=common
17
+
18
+ DOTENV_CONFIG_QUIET=true
package/README.md ADDED
@@ -0,0 +1,115 @@
1
+ # @open-xchange/soap-client
2
+
3
+ This project provides an API facade for the OX App Suite Middleware SOAP API, making it easy to interact with provisioning endpoints such as contexts, users, secondary accounts, and more.
4
+
5
+ ## Features
6
+
7
+ - **API Facade:** Programmatically access and manage OX App Suite resources via a simple JavaScript API.
8
+ - **Provisioning Script:** Easily create, update, and delete contexts, users, and secondary accounts from the command line.
9
+ - **Configurable:** Uses `.env` files for environment-specific configuration.
10
+
11
+ ## Usage
12
+
13
+ ### CLI Provisioning
14
+
15
+ You can use the built-in provisioning script to automate resource creation. Simply run:
16
+
17
+ ```sh
18
+ npx @open-xchange/soap-client
19
+ ```
20
+ If you already have installed the package in your project, you can run the script directly:
21
+
22
+ ```sh
23
+ pnpm provision.js
24
+ ```
25
+
26
+ This will execute the provisioning tool, which reads configuration from a JSON file (default: `./provisioning.json`). You can specify a different file with the `-f` option:
27
+
28
+ ```sh
29
+ npx @open-xchange/soap-client -f example-provisioning.json
30
+ ```
31
+ The JSON file should contain the resources to provision. For example:
32
+
33
+ ```json
34
+ {
35
+ "contexts": [
36
+ {
37
+ "data": {
38
+ "name": "test",
39
+ "capabilities": "foo,bar",
40
+ "config": {
41
+ "entries": [{
42
+ "key": "config",
43
+ "value": {
44
+ "entries": [
45
+ { "key": "io.ox/core//foobar", "value": "false" }
46
+ ]
47
+ }
48
+ }]
49
+ }
50
+ },
51
+ "users": [
52
+ {
53
+ "name": "testuser",
54
+ "primaryEmail": "testuser-123@example.com",
55
+ "display_name": "Test User",
56
+ "imapLogin": "testuser-123",
57
+ "imapServer": "main-dovecot",
58
+ "smtpServer": "main-postfix",
59
+ "email1": "testuser-123@box.ox.io",
60
+ "password": "supersecret",
61
+ "sur_name": "User",
62
+ "given_name": "Test"
63
+ }
64
+ ],
65
+ "secondaryAccount":
66
+ {
67
+ "name": "info",
68
+ "login": "info@example.com",
69
+ "primaryAddress": "info@example.com",
70
+ "mailEndpointSource": "primary",
71
+ "transportEndpointSource": "primary",
72
+ "personal": "Info"
73
+ }
74
+ }
75
+ ]
76
+ }
77
+ ```
78
+
79
+ ### Example: Creating Resources
80
+
81
+ The CLI supports creating contexts, users, and secondary accounts:
82
+
83
+ ```sh
84
+ npx @open-xchange/soap-client create context --name my-context
85
+ npx @open-xchange/soap-client create user --context-id 123 --email user@example.com --name myuser
86
+ npx @open-xchange/soap-client create account --context-id 123 --name info --email info@example.com --users 1,2,3
87
+ ```
88
+
89
+ ### Example: Deleting Resources
90
+
91
+ ```sh
92
+ npx @open-xchange/soap-client delete context --id 123
93
+ npx @open-xchange/soap-client delete user --context-id 123 --id 456
94
+ npx @open-xchange/soap-client delete account --context-id 123 --email info@example.com --users 1,2,3
95
+ ```
96
+
97
+ ## API Usage
98
+
99
+ You can also use the API programmatically in your Node.js projects and choose between either the common or the reseller API when doing so by importing the respective service:
100
+
101
+
102
+ ```js
103
+ import { contextService, userService } from '@open-xchange/soap-client/common'
104
+
105
+ const context = await contextService.create({ name: 'my-context' })
106
+ const user = await userService.create(context, { name: 'myuser', email1: 'user@example.com' })
107
+ ```
108
+
109
+ ## Configuration
110
+
111
+ Set up your `.env` file with the required environment variables. See `.env.default` for an example.
112
+
113
+ ---
114
+
115
+ For more details, see the [bin/provision.js](bin/provision.js) script and the [services](services/) directory.
package/bin/provision.js CHANGED
@@ -33,7 +33,10 @@ function checkEnvironmentVariables () {
33
33
  }
34
34
 
35
35
  async function getOrCreateContext (data) {
36
- const contextData = { ...{ maxQuota: -1 }, ...data }
36
+ const contextData = {
37
+ ...{ maxQuota: -1 },
38
+ ...data
39
+ }
37
40
  let context
38
41
  try {
39
42
  const existingContext = await contextService.list(contextData.id || contextData.name)
@@ -47,7 +50,7 @@ async function getOrCreateContext (data) {
47
50
  }
48
51
  return {
49
52
  ...context,
50
- ...contextAdmin
53
+ admin: data.admin || contextAdmin.admin
51
54
  }
52
55
  } catch (error) {
53
56
  console.error('Error in context operation:', error)
@@ -72,13 +75,14 @@ async function getOrCreateUser (context, userData) {
72
75
 
73
76
  async function getOrCreateSecondaryAccount (accountData, context, users) {
74
77
  try {
75
- const existingAccounts = (await secondaryAccountService.list(context, users)).filter(acc => acc.name === accountData.name)
78
+ const existingAccounts = (await secondaryAccountService.list(context, users))
76
79
  if (existingAccounts?.length > 0) {
80
+ const filteredAccounts = existingAccounts.filter(acc => acc.primaryAddress === accountData.primaryAddress)
77
81
  const usersWithoutAccount = users.filter(user => {
78
- const hasAccount = existingAccounts.some(acc => acc.userId === user.id)
82
+ const hasAccount = filteredAccounts.some(acc => acc.userId === user.id)
79
83
  return !hasAccount
80
84
  })
81
- if (usersWithoutAccount.length === 0) return existingAccounts[0]
85
+ if (usersWithoutAccount.length === 0) return filteredAccounts[0]
82
86
  return await secondaryAccountService.create(accountData, context, usersWithoutAccount)
83
87
  }
84
88
  console.log('Creating new secondary account')
@@ -104,8 +108,7 @@ async function provisionFromFile (configPath) {
104
108
  for (const contexts of config.contexts || []) {
105
109
  try {
106
110
  const contextData = contexts.data
107
- const context = await getOrCreateContext(contexts.data.name)
108
-
111
+ const context = await getOrCreateContext({ name: contexts.data.name, admin: contexts.data.admin })
109
112
  if (contextData.capabilities) {
110
113
  try {
111
114
  await contextService.changeCapabilities(context.id, contextData.capabilities, undefined)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-xchange/soap-client",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "SOAP client for OX App Suite",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -20,10 +20,10 @@
20
20
  "author": "",
21
21
  "license": "AGPL-3.0-or-later",
22
22
  "dependencies": {
23
- "commander": "^13.1.0",
24
- "dotenv": "^16.4.5",
23
+ "commander": "^14.0.0",
24
+ "dotenv": "^17.2.0",
25
25
  "p-retry": "^6.2.1",
26
- "soap": "^1.1.10"
26
+ "soap": "^1.1.12"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@open-xchange/lint": "0.2.0"
@@ -1,11 +1,9 @@
1
1
  import * as oxaasService from './oxaas.js'
2
2
  import * as resellerContextService from './resellerContext.js'
3
3
  import * as resellerUserService from './resellerUser.js'
4
- import * as secondaryAccountService from '../secondaryAccount.js'
5
4
 
6
5
  export {
7
6
  oxaasService,
8
7
  resellerContextService,
9
- resellerUserService,
10
- secondaryAccountService
8
+ resellerUserService
11
9
  }
package/soap.js CHANGED
@@ -26,8 +26,7 @@ import pRetry, { AbortError as RetryAbortError } from 'p-retry'
26
26
  // Set AbortError correctly
27
27
  const AbortError = RetryAbortError
28
28
 
29
- dotenv.config({ path: '.env' })
30
- dotenv.config({ path: '.env.defaults' })
29
+ dotenv.config({ path: ['.env', '.env.defaults'], quiet: true })
31
30
 
32
31
  // This flag enables debug output including timing information.
33
32
  const debug = process.env.DEBUG_SOAP === 'true'