Error when trying to create a user via API

Nextcloud version (eg, 18.0.2): 20.0.0 stable
Operating system and version (eg, Ubuntu 20.04): Plesk
Apache or nginx version (eg, Apache 2.4.25): nginx 1.18.0-v.debian.9+p18.0.30.0+t200826.0942
PHP version (eg, 7.1): 7.4

The issue you are facing:
I always get an error when I try to create a user with the user provisioning API in nodejs

Is this the first time you’ve seen this error? (Y/N): N

Steps to replicate it:

  1. Create the code
  2. Run the desired action to create a user
  3. See the error in console

My nodejs logs:

statusCode: 401
<?xml version="1.0"?>
<ocs>
 <meta>
  <status>failure</status>
  <statuscode>997</statuscode>
  <message>Current user is not logged in</message>
  <totalitems></totalitems>
  <itemsperpage></itemsperpage>
 </meta>
 <data/>
</ocs>

The output of your config.php file in /path/to/nextcloud (make sure you remove any identifiable information!):

<?php
$CONFIG = array (
  'passwordsalt' => 'removed',
  'secret' => 'removed',
  'trusted_domains' => 
  array (
    0 => 'localhost',
    1 => 'cloud.infinity-systems.eu',
  ),
  'datadirectory' => '/var/www/vhosts/1850.webhost-02.my-host.network/.nextcloud/data/0a6811a1c3f9',
  'dbtype' => 'mysql',
  'version' => '20.0.0.9',
  'overwrite.cli.url' => 'http://localhost',
  'dbname' => 'nextcloud_5d62f30d',
  'dbhost' => 'localhost:3306',
  'dbport' => '',
  'dbtableprefix' => 'oc_',
  'mysql.utf8mb4' => true,
  'dbuser' => 'ncuser_5d62f30d',
  'dbpassword' => 'removed',
  'installed' => true,
  'instanceid' => 'occfdylare55',
  'mail_smtpmode' => 'smtp',
  'mail_smtpauthtype' => 'LOGIN',
  'mail_sendmailmode' => 'smtp',
  'mail_smtpauth' => 1,
  'mail_from_address' => 'no-reply',
  'mail_domain' => 'infinity-systems.eu',
  'mail_smtphost' => 'webhost-02.my-host.network',
  'mail_smtpport' => '25',
  'mail_smtpname' => 'no-reply@infinity-systems.eu',
  'mail_smtppassword' => 'removed',
);

The output of your Apache/nginx/system log in /var/log/____:

2020-10-10 13:42:50	162.158.158.13	401	POST /ocs/v1.php/cloud/users HTTP/1.1

The nodejs code I use to create the user:

const https = require('https')
const message = removed
const user = removed
const pw = removed

const data = JSON.stringify({
  userid: user,
  password: pw,
})

const options = {
  hostname: 'cloud.infinity-systems.eu',
  baseURL: 'https://cloud.infinity-systems.eu/ocs/v1.php/cloud/',
  url: 'cloud.infinity-systems.eu',
  path: '/ocs/v1.php/cloud/users',
  method: 'POST',
  headers: {
    'OCS-APIRequest': 'true',
    'Authorization': 'Basic "Base64(removed:removed)"',
	'Content-Type': 'application/x-www-form-urlencoded',
  },
}

const req = https.request(options, (res) => {
  console.log(`statusCode: ${res.statusCode}`)

  res.on('data', (d) => {
    process.stdout.write(d)
  })
})

req.on('error', (error) => {
  console.error(error)
})

req.write(data)
req.end()
1 Like

We have the same error and would be happy if someone could help. @jospoortvliet: Is this also sales department or is this forum a good place?

Do you use 2-Factor Authentification?
Then your user PW does not work, you need a App-Token.

No, I don’t use 2FA

Ok. I took a deep dive. You must change your Base64 - encoding Method.

const creds = Buffer.from("username:password").toString('base64')

and then change this line:
'Authorization': 'Basic "Base64(removed:removed)"',
to
Authorization': 'Basic ' + creds

Works.

Thanks a lot for your answers.

I made the changes you told me but now I got the following error

statusCode: 200
<?xml version="1.0"?>
<ocs>
 <meta>
  <status>failure</status>
  <statuscode>998</statuscode>
  <message>Invalid query, please check the syntax. API specifications are here: http://www.freedesktop.org/wiki/Specifications/open-collaboration-services.
</message>
 </meta>
 <data/>
</ocs>

(my code now)

const https = require('https')
const user = removed
const pw = removed

const data = JSON.stringify({
  userid: user,
  password: pw,
})

const creds = Buffer.from("removed:removed").toString('base64')

const options = {
  hostname: 'cloud.infinity-systems.eu',
  baseURL: 'https://cloud.infinity-systems.eu/ocs/v1.php/cloud/',
  url: 'cloud.infinity-systems.eu',
  path: '/ocs/v1.php/cloud/users',
  method: 'POST',
  headers: {
    'OCS-APIRequest': 'true',
    'Authorization': 'Basic ' + creds,
	'Content-Type': 'application/x-www-form-urlencoded',
  },
}

const req = https.request(options, (res) => {
  console.log(`statusCode: ${res.statusCode}`)

  res.on('data', (d) => {
    process.stdout.write(d)
  })
})

req.on('error', (error) => {
  console.error(error)
})

req.write(data)
req.end()

Your request queries for the users. That is a GET request.

`

const options = {
  hostname: 'xxxxx',
  path: '/ocs/v1.php/cloud/users',
  method: 'GET',
  headers: {
    'OCS-APIRequest': 'true',
    'Authorization': 'Basic ' +  creds,
	'Content-Type': 'application/x-www-form-urlencoded',
  },
}

yes, but I want to create a user

Then you have to do a POST request and change your path to something like that:

/ocs/v1.php/cloud/users -d userid="username" -d password="SeCrEt"

see:

But that only works if I run a normal curl command. But I use node.js with native https module and there you can’t edit the path like you suggested

Just JavaScript, simple string concatenation:

path: '/ocs/v1.php/cloud/users' + '-d userid=' + username + '-d password=' + password ,

Or do it like so:

const querystring = require('querystring');
const https = require('https')

//replace "admin:admin" by "admin-user:admin-pass" 
const creds = Buffer.from("admin:admin").toString('base64')

// new User data:
const data = querystring.stringify({
  userid: 'hulk',
  password: '123'
})

// connection params
const options = {
  hostname: 'example.com',
  path: '/ocs/v1.php/cloud/users',
  method: 'POST',
  headers: {
    'OCS-APIRequest': 'true',
    'Authorization': 'Basic ' +  creds,
    'Content-Type': 'application/x-www-form-urlencoded',
	  'Content-Length': data.length
  },
}

// request
const req = http.request(options, (res) => {
  console.log( data , options )
  console.log(`statusCode: ${res.statusCode}`)

  res.on('data', (d) => {
    process.stdout.write(d)
  })
})

req.on('error', (error) => {
  console.error(error)
})

req.write(data)
req.end()

You are lucky, I’m working at that problem too :wink:

2 Likes

I’m so thankful, that works finally :tada:

Many thanks for helping

1 Like