// $Id$
// @ts-check
'use strict';
import { RestServices } from '../tools/RestServices.js';
import { ApiResponse } from '../tools/ApiResponse.js';
import { Context } from './Context.js';
import { Licence, LicenceServices } from './Licence.js';
/**
*
* @category COLNEO infohub
*
* @classdesc
* COLNEO infohub Scope. <br>
* Each scope defines the boundary at which resources are managed in a database and isolated,
* typically tied to a tenant that represents an organization or licensee.
*
* @property {object} info - Scope info
* @property {Licence[]} licences - Licences
*
*
* @example {
* "info": {
* "id": "scope1",
* "name": "Scope 1",
* "description": "Scope 1 description",
* "createdon": "2025-01-01",
* "updatedon": "2025-01-01",
* "createdby": "user1",
* "updatedby": "user1"
* },
* "licences": [
* {
* "contract": "",
* "created": "2025-01-01T00:00:00Z",
* "createdby": "user@example.com",
* "expirated": null,
* "id": "00000000-0000-0000-0000-000000000000",
* "licenced_userid": ["user@example.com"],
* "licencee": {
* "address": "{\"street\":\"...\", \"city\":\"...\", \"zip\":\"...\"}",
* "email": "info@example.com",
* "name": "ACME"
* },
* "maxpermissions": "edit",
* "maxseats": 0,
* "module": "objecttypes",
* "scope": "cn_dv",
* "startdate": "2025-01-01T00:00:00Z",
* "updated": "2025-01-01T00:00:00Z",
* "updatedby": "user@example.com"
* },
* ]
* }
*
* @since 09.2025, aab, jh
*
*/
export class Scope {
/**
* Since scope information is retrieved from COLNEO infohub, this constructor is not
* called directly. Use factory method `ScopeServicves.getScope()` instead.
*
* @since 09.2025, aab
*/
constructor(info = {}) {
Object.assign(this, info);
}
/**
*
* @param {*} data
* @returns {void}
*/
setData(data = /** @type {object} */ ({})) {
Object.assign(this, data);
}
/**
*
* @returns {object} Scope data without function properties
*/
getData() {
return Object.fromEntries(Object.entries(this).filter(([_, v]) => typeof v !== 'function'));
}
}
/**
*
* @category COLNEO infohub
*
* @classdesc
* Functions to get scope information from infohub.
*
*/
export class ScopeServices {
/**
* @since 1.0, 09.2025, aab
* @param {Context} ctx - Context instance
*
*/
constructor(ctx) {
this._ctx = ctx;
}
/**
* Get scope from COLNEO infohub
* @returns {Promise<ApiResponse>} data: Scope
* @param {string} scopeid - Scope ID
*/
async getScopeById(scopeid) {
if (!scopeid) {
return new ApiResponse(400, null);
}
try {
const url = `${this._ctx.getServiceUrl(Context.SERVICE.IDP)}/admin/scopes/${scopeid}`;
const res = await RestServices.makeApiCall(this._ctx.getToken(), RestServices.METHODS.GET, url);
const scope = new Scope(res.data || {});
return res.status < 300 ? new ApiResponse(200, scope) : new ApiResponse(res.status, null, res.message);
} catch (error) {
return new ApiResponse(500, null);
}
}
/**
* Get scopes of a user by user ID
* @since 09.2025, aab
* @param {string} userid - User ID
* @returns {Promise<ApiResponse>}
*/
async getScopesOfUser(userid) {
if (!userid) {
return new ApiResponse(400, null);
}
try {
const url = `${this._ctx.getServiceUrl(Context.SERVICE.IDP)}/users/${userid}/scopelist`;
const res = await RestServices.makeApiCall(this._ctx.getToken(), RestServices.METHODS.GET, url);
const arr = Array.isArray(res.data) ? /** @type {any[]} */ (res.data) : [];
const list = arr.map((d) => new Scope(d));
return res.status < 300 ? new ApiResponse(200, list) : new ApiResponse(res.status, null, res.message);
} catch (error) {
return new ApiResponse(500, null);
}
}
/**
* Get licences within a scope
* @param {string} scopeid - Scope ID
* @returns {Promise<ApiResponse>}
*/
async getLicencesOfScope(scopeid) {
if (!scopeid) {
return new ApiResponse(400, null);
}
try {
const licenceServices = new LicenceServices(this._ctx);
const licences = await licenceServices.getLicences({ scope: scopeid });
const list = Array.isArray(licences.data) ? /** @type {Licence[]} */ (licences.data) : [];
const scope = new Licence(list);
return licences.status < 300 ? new ApiResponse(200, scope) : new ApiResponse(licences.status, null, licences.message);
} catch (error) {
return new ApiResponse(500, null);
}
}
/**
* Get scope groups
* @param {string} id - Scope ID
* @param {object} query - Query object containing filter, members, etc.
* @param {string} [query.filter] - Filter
* @param {string} [query.members] - Members
* @returns {Promise<ApiResponse>}
*/
async getScopeGroups(id, query) {
if (!id) {
return new ApiResponse(400, null);
}
const queryString = this.#buildQueryString(query);
const url = `${this._ctx.getServiceUrl(Context.SERVICE.USR)}/${id}/usergroups`;
try {
const res = await RestServices.makeApiCall(this._ctx.getToken(), RestServices.METHODS.GET, url + queryString);
return res.status < 300 ? new ApiResponse(200, res.data) : new ApiResponse(res.status, null, res.message);
} catch (_) {
return new ApiResponse(500, null);
}
}
/**
* Get scope roles
* @param {string} id - Scope ID
* @param {object} query - Query object containing filter, members, etc.
* @param {string} [query.filter] - Filter
* @param {string} [query.members] - Members
* @returns {Promise<ApiResponse>}
*/
async getScopeRoles(id, query) {
if (!id) {
return new ApiResponse(400, null);
}
const queryString = this.#buildQueryString(query);
try {
const url = `${this._ctx.getServiceUrl(Context.SERVICE.USR)}/${id}/userroles`;
const res = await RestServices.makeApiCall(this._ctx.getToken(), RestServices.METHODS.GET, url + queryString);
return res.status < 300 ? new ApiResponse(200, res.data) : new ApiResponse(res.status, null, res.message);
} catch (_) {
return new ApiResponse(500, null);
}
}
/**
* Create scope
* @param {object} ScopeInfo_new - Scope information
* @param {string} [ScopeInfo_new.name] - Scope name
* @param {string} [ScopeInfo_new.description] - Scope description
* @returns {Promise<ApiResponse>}
*/
async createScope(ScopeInfo_new) {
if (!ScopeInfo_new?.name) {
return new ApiResponse(400, null);
}
try {
const url = `${this._ctx.getServiceUrl(Context.SERVICE.IDP)}/admin/scopes`;
const res = await RestServices.makeApiCall(this._ctx.getToken(), RestServices.METHODS.POST, url, ScopeInfo_new);
return res.status < 300 ? new ApiResponse(200, res.data) : new ApiResponse(res.status, null, res.message);
} catch (_) {
return new ApiResponse(500, null);
}
}
/**
* Update scope
* @param {string} id - Scope ID
* @param {object} ScopeInfo_update - Scope information
* @param {string} [ScopeInfo_update.name] - Scope name
* @param {string} [ScopeInfo_update.description] - Scope description
* @returns {Promise<ApiResponse>}
*/
async updateScope(id, ScopeInfo_update) {
if (!id || !ScopeInfo_update?.name) {
return new ApiResponse(400, null);
}
try {
const url = `${this._ctx.getServiceUrl(Context.SERVICE.IDP)}/admin/scopes/${id}`;
const res = await RestServices.makeApiCall(this._ctx.getToken(), RestServices.METHODS.PUT, url, ScopeInfo_update);
return res.status < 300 ? new ApiResponse(200, res.data) : new ApiResponse(res.status, null, res.message);
} catch (_) {
return new ApiResponse(500, null);
}
}
/**
* Delete scope
* @param {string} id - Scope ID
* @returns {Promise<ApiResponse>}
*/
async deleteScope(id) {
if (!id) {
return new ApiResponse(400, null);
}
try {
const url = `${this._ctx.getServiceUrl(Context.SERVICE.IDP)}/admin/scopes/${id}`;
const res = await RestServices.makeApiCall(this._ctx.getToken(), RestServices.METHODS.DELETE, url);
return res.status < 300 ? new ApiResponse(200, res.data) : new ApiResponse(res.status, null, res.message);
} catch (_) {
return new ApiResponse(500, null);
}
}
/**
* Query string builder
* @param {object} [query] - Query object containing filter, members, etc.
* @param {string} defaultMember - Default member value if not specified
* @returns {string} - Properly formatted query string
*/
#buildQueryString(query = /** @type {object} */ ({}), defaultMember = 'info') {
let queryString = '';
let c = '?';
if (query['filter']) {
queryString += c + 'filter=' + encodeURIComponent(query['filter']);
c = '&';
}
if (query['members']) {
let membersString = query['members'];
if (defaultMember && !membersString.includes(defaultMember)) {
membersString = membersString + ',' + defaultMember;
}
queryString += c + 'members=' + encodeURIComponent(membersString);
c = '&';
} else if (defaultMember) {
queryString += c + 'members=' + encodeURIComponent(defaultMember);
c = '&';
}
return queryString;
}
}
Source