Thanks, I hoped I wouldn’t have to code stuff. But okay.
Below the script I was using (in case someone else needs this to conform to EU law in their use case, I was surprised as I thought this would be a more common request)
Note, that count=0 does not work as the documentation says, albeit I configured Settings/General/REST API to unlimited to work. I worked around by configuring a ridiculously large limit as max and using that instead.
Also contrary to the documentation when getting userlist as an admin, I did not get all the fields by default, I explicitly had to request for lastLogin. (The only admin-only field the script cares about).
I’m certain there are a lot of Node.JS libraries I could have used to wrap get/post requests; I prefer to use the Node.JS core API directly tough.
Thanks, Axel
const http = require( 'http' );
const util = require( 'util' );
const expireDays = 180;
const dont =
{
'axkibe': true,
};
const now = Date.now( );
const utilOpts = { depth: 50 };
console.inspect = function( ...args )
{
for( let a = 0, alen = args.length; a < alen; a++ )
args[ a ] = util.inspect( args[ a ], utilOpts );
console.log.apply( console.log, args );
};
const get = function( url, headers )
{
return new Promise( ( resolve, reject ) => {
const req = http.request( {
headers: headers,
hostname: 'localhost',
path: '/api/v1/' + url,
port: 3000,
}, ( res ) => {
res.setEncoding( 'utf8' );
let body = '';
res.on( 'data', ( o ) => body += o );
res.on( 'end', ( ) => resolve( JSON.parse( body ) ) );
} );
req.on( 'error', ( e ) => reject( e ) );
req.end( );
} );
};
const post = function( url, headers, data )
{
return new Promise( ( resolve, reject ) => {
const req = http.request( {
headers: headers,
hostname: 'localhost',
method: 'POST',
path: '/api/v1/' + url,
port: 3000,
}, ( res ) => {
res.setEncoding( 'utf8' );
let body = '';
res.on( 'data', ( o ) => body += o );
res.on( 'end', ( ) => resolve( JSON.parse( body ) ) );
} );
req.on( 'error', ( e ) => reject( e ) );
req.write( JSON.stringify( data ) );
req.end( );
} );
};
const run = async function( )
{
console.log( '* authenticating' );
const auth = await post( 'login', { }, { user: 'axkibe', password: 'xxx' } );
//console.inspect( auth );
const headers = { 'X-Auth-Token': auth.data.authToken, 'X-User-Id': auth.data.userId };
console.log( '* listing' );
const list =
await get(
encodeURI('users.list?fields={"lastLogin":1}&count=9999999999999'),
headers
);
//console.inspect( list );
console.log( '* building expired list' );
const expired = [ ];
for( let user of list.users )
{
const last = Date.parse( user.lastLogin );
const days = Math.floor( ( now - last ) / ( 1000 * 60 * 60 * 24 ) );
if( isNaN( days) ) continue;
if( dont[ user.username ] ) continue;
if( days <= expireDays ) continue;
console.log( '**', user.username, days );
expired.push( user );
}
console.log( '* deleting' );
for( let user of expired )
{
console.log( '**', user.username );
await post( 'users.delete', headers, { userId: user._id, confirmRelinquish: true } );
}
};
run( );