UNPKG

@researchdatabox/sails-hook-redbox-labarchives

Version:
397 lines 41.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Controllers = void 0; require("rxjs/add/operator/map"); /** * Package that contains all Controllers. */ const redbox_core_types_1 = require("@researchdatabox/redbox-core-types"); const Config_1 = require("../Config"); const UserInfo_1 = require("../UserInfo"); var Controllers; (function (Controllers) { /** * Omero related features.... * */ class LabarchivesController extends redbox_core_types_1.Controllers.Core.Controller { _exportedMethods = [ 'info', 'rdmpInfo', 'login', 'link', 'checkLink', 'list', 'createNotebook' ]; config = new Config_1.Config(); logHeader = "LabArchivesController::"; info(req, res) { this.config.set(); this.config.brandingAndPortalUrl = BrandingService.getFullPath(req); this.ajaxOk(req, res, null, { location: this.config.location, status: true }); } async rdmpInfo(req, res) { this.config.set(); const userId = req.user.id; const rdmp = req.param('rdmp'); let recordMetadata = {}; this.config.brandingAndPortalUrl = BrandingService.getFullPath(req); let infoResp = { status: false, message: "Error retrieving associated RDMP, please contact an administrator." }; try { recordMetadata = await RecordsService.getMeta(rdmp); if (recordMetadata) { infoResp.status = true; infoResp['recordMetadata'] = recordMetadata['metadata']; } } catch (err) { sails.log.error(`${this.logHeader} rdmpInfo() -> Failed to get metadata:`); sails.log.error(err); } if (infoResp.status === false) { this.ajaxFail(req, res, infoResp.message, infoResp); } else { this.ajaxOk(req, res, null, infoResp); } } async login(req, res) { this.config.set(); const user = { username: req.param('username'), password: req.param('password') }; const loginResp = { status: false, message: 'Username and/or password invalid' }; if (user.username && user.password) { let info = {}; const userId = req.user.id; this.config.brandingAndPortalUrl = BrandingService.getFullPath(req); try { let userInfo = await sails.services.labarchivesservice.login(this.config.key, user.username, user.password); if (userInfo && userInfo['users']) { userInfo = userInfo['users']; info = new UserInfo_1.UserInfo(userInfo['id'], userInfo['orcid'], userInfo['fullname']); const workspaceInfo = await WorkspaceService.workspaceAppFromUserId(userId, this.config.appName).toPromise(); if (workspaceInfo && workspaceInfo['id']) { await WorkspaceService.updateWorkspaceInfo(workspaceInfo['id'], info).toPromise(); } else { await WorkspaceService.createWorkspaceInfo(userId, this.config.appName, info).toPromise(); } loginResp.status = true; loginResp['login'] = true; } } catch (err) { sails.log.error(`${this.logHeader} login() -> Error: `); sails.log.error(err); loginResp.message = `Error logging in, please contact an administrator.`; } } else { loginResp.message = 'Missing username and/or password'; } if (loginResp.status === true) { this.ajaxOk(req, res, null, loginResp); } else { this.ajaxFail(req, res, loginResp.message, loginResp); } } async list(req, res) { this.config.set(); const userId = req.user.id; this.config.brandingAndPortalUrl = BrandingService.getFullPath(req); let listResp = { status: false, message: `Failed to retrieve list, please contact and administrator.` }; try { const workspaceApp = await WorkspaceService.workspaceAppFromUserId(userId, this.config.appName).toPromise(); let user = null; if (!workspaceApp) { user = null; } else { user = workspaceApp['info'] || null; } if (user) { const userInfo = await sails.services.labarchivesservice.userInfo(this.config.key, user['id'], true); if (userInfo) { let resNotebooks = userInfo['users']['notebooks']; let notebooks = { '$': { type: 'array' }, notebook: [] }; if (Array.isArray(resNotebooks['notebook'])) { notebooks['notebook'] = resNotebooks['notebook']; } else { if (resNotebooks['notebook']) { notebooks['notebook'] = [resNotebooks['notebook']]; } } listResp.status = true; listResp['notebooks'] = notebooks; listResp.message = 'list'; } else { listResp.message = `Failed to get user information, please contact an administrator.`; sails.log.error(`${this.logHeader} list() -> failed to retrieve user info`); } } else { listResp.message = `Failed to get workspace information, please contact an administrator.`; sails.log.error(`${this.logHeader} list() -> Failed to get workspace app info`); } } catch (err) { sails.log.error(`${this.logHeader} list() -> Failed to list:`); sails.log.error(err); } // send response if (listResp.status === true) { this.ajaxOk(req, res, listResp.message, listResp); } else { this.ajaxFail(req, res, listResp.message, listResp); } } async link(req, res) { this.config.set(); const userId = req.user.id; const username = req.user.username; this.config.brandingAndPortalUrl = BrandingService.getFullPath(req); const rdmp = req.param('rdmp'); const notebook = req.param('workspace'); if (!notebook || !rdmp) { const message = 'rdmp, notebook are missing'; this.ajaxFail(req, res, message, { status: false, message: message }); return; } const nbId = notebook['id']; const nbName = notebook['name']; sails.log.debug('notebook: ' + nbId); sails.log.debug('name: ' + nbName); if (!nbId || !nbName) { const message = 'notebook or notebook name are missing'; this.ajaxFail(req, res, message, { status: false, message: message }); return; } let info = {}; let workspaceId = null; let metadataContent = ''; let rdmpTitle = ''; let recordMetadata = null; const linkResp = { status: false, message: `Failed to link, please contact an administrator.` }; try { recordMetadata = (await RecordsService.getMeta(rdmp))?.metadata; if (recordMetadata) { rdmpTitle = recordMetadata.title; info = (await WorkspaceService.workspaceAppFromUserId(userId, this.config.appName).toPromise())?.info; if (info) { const record = { rdmpOid: rdmp, rdmpTitle: rdmpTitle, title: nbName, location: this.config.location, //`https://au-mynotebook.labarchives.com`, description: this.config.description, //'LabArchives Workspace', type: this.config.recordType }; const createResp = await WorkspaceService.createWorkspaceRecord(this.config, username, record, this.config.recordType, this.config.workflowStage).toPromise(); if (createResp) { workspaceId = createResp.data.workspaceOid; const insertNodeResp = await sails.services.labarchivesservice.insertNode(this.config.key, info['id'], nbId, 'stash.workspace', false); if (insertNodeResp && insertNodeResp['tree-tools']) { const tree = insertNodeResp['tree-tools']; const node = tree['node']; metadataContent = ` <div id="${workspaceId}"> <h1>UTS</h1> <h3>Workspace <strong>${nbName}</strong> is linked to:</h3> <h2>Research Data Management Plan <a href="${this.config.brandingAndPortalUrl}/record/view/${rdmp}">${rdmpTitle}</a></h2> <p>Stash Id: ${workspaceId}</p> </div> `; const partType = 'text entry'; const insertNode = await sails.services.labarchivesservice.addEntry(this.config.key, info['id'], nbId, node['tree-id'], partType, metadataContent); if (insertNode) { linkResp.status = true; linkResp.message = 'workspaceRecordCreated'; } else { sails.log.error(`${this.logHeader} link() -> Failed in sails.services.labarchivesservice.addEntry`); } } else { sails.log.error(`${this.logHeader} link() -> LabArchives insertNode failed:`); sails.log.error(insertNodeResp); } } else { sails.log.error(`${this.logHeader} link() -> Failed to create workspace record.`); } } else { sails.log.error(`${this.logHeader} link() -> Failed to get workspace app info.`); } } else { linkResp.message = `Failed to get RDMP, please contact an administrator.`; } } catch (err) { sails.log.error(`${this.logHeader} link() -> Failed to link:`); sails.log.error(err); } // send response if (linkResp.status === true) { this.ajaxOk(req, res, null, linkResp); } else { this.ajaxFail(req, res, linkResp.message, linkResp); } } async checkLink(req, res) { this.config.set(); const userId = req.user.id; const username = req.user.username; const rdmp = req.param('rdmp'); const nbId = req.param('nbId'); const workspace = req.param('workspace'); let info = {}; let check = { link: '' }; this.config.brandingAndPortalUrl = BrandingService.getFullPath(req); const checkLinkResp = { status: false, message: `Failed to check link, please contact an administrator.` }; try { info = await WorkspaceService.workspaceAppFromUserId(userId, this.config.appName).toPromise(); if (info) { info = info['info']; const nbTree = await sails.services.labarchivesservice.getNotebookTree(this.config.key, info['id'], nbId, 0); if (nbTree['tree-tools'] && nbTree['tree-tools']['level-nodes']) { const lvlNodes = nbTree['tree-tools']['level-nodes']; const nodes = lvlNodes['level-node']; if (Array.isArray(nodes)) { nodes.map(node => { if (node['display-text'] === 'stash.workspace') { check.link = 'linked'; } }); } } checkLinkResp['check'] = check; checkLinkResp.message = 'checkLink'; checkLinkResp.status = true; } else { sails.log.error(`${this.logHeader} checkLink() -> Failed to get workspace app info`); } } catch (err) { sails.log.error(`${this.logHeader} checkLink() -> Failed to check link:`); sails.log.error(err); } // sending response if (checkLinkResp.status === true) { this.ajaxOk(req, res, null, checkLinkResp); } else { this.ajaxFail(req, res, checkLinkResp.message, checkLinkResp); } } async createNotebook(req, res) { this.config.set(); const userId = req.user.id; const name = req.param('name'); const userEmail = req.param('userEmail'); let supervisor = req.param('supervisor'); const rdmp = req.param('rdmp'); let recordMetadata = {}; let rdmpTitle = ''; let info = {}; let nb; this.config.brandingAndPortalUrl = BrandingService.getFullPath(req); let createResponse = await RecordsService.getMeta(rdmp); const contactAdmin = `please contact an administrator`; try { if (!_.isEmpty(createResponse)) { recordMetadata = createResponse.metadata; sails.log.debug(`${this.logHeader} createNotebook() -> recordMetadata:`); sails.log.debug(recordMetadata); rdmpTitle = recordMetadata['title']; const supervisorFromRDMP = recordMetadata['contributor_ci']['email']; if (supervisor === supervisorFromRDMP) { const info = (await WorkspaceService.workspaceAppFromUserId(userId, this.config.appName).toPromise())?.info; sails.log.debug('userHasEmail'); const supervisorHasEmail = await sails.services.labarchivesservice.userHasEmail(this.config.key, supervisor); if (supervisorHasEmail && supervisorHasEmail['users'] && supervisorHasEmail['users']['account-for-email']['_']) { sails.log.debug(`${this.logHeader} createNotebook() -> Has supervisor email, creating notebook: ${name}`); const result = await sails.services.labarchivesservice.createNotebook(this.config.key, info['id'], name); sails.log.verbose(`${this.logHeader} createNotebook: `); sails.log.verbose(result); if (result && result.notebooks) { nb = result.notebooks; if (userEmail.toLowerCase() === supervisor.toLowerCase()) { createResponse = { status: true, response: nb }; } else { const addUser = await sails.services.labarchivesservice.addUserToNotebook(this.config.key, info['id'], nb['nbid'], supervisor, 'ADMINISTRATOR'); sails.log.debug('addUser'); if (addUser) { const nbu = addUser.notebooks['notebook-user']; sails.log.debug(nbu); createResponse = { status: true, response: nb }; } else { sails.log.error(`${this.logHeader} createNotebook() -> Cannot add user to notebook`); createResponse = { status: false, message: 'Cannot add user to notebook, please contact an administrator.' }; } } } else { sails.log.error(`${this.logHeader} createNotebook() -> Notebook not created:`); createResponse = { status: false, message: 'Failed to create notebook, please contact an administrator.' }; } } else { const message = `Supervisor not found in LabArchives: ${supervisor}`; sails.log.error(`${this.logHeader} createNotebook() -> ${message}`); createResponse = { status: false, message: `${message}, ${contactAdmin}` }; } } else { const message = `Supervisor email does not match workspace: ${supervisor} === ${supervisorFromRDMP}`; sails.log.error(`${this.logHeader} createNotebook() -> ${message}`); createResponse = { status: false, message: `${message}, ${contactAdmin}` }; } } else { const message = `RDMP Not found: ${rdmp}`; sails.log.error(`${this.logHeader} createNotebook() -> ${message}`); createResponse = { status: false, message: `${message}, ${contactAdmin}` }; } } catch (err) { sails.log.error(`${this.logHeader} createNotebook() -> Error thrown while processing: `); sails.log.error(err); createResponse = { status: false, message: err.message }; } // handle failure try { if (createResponse.status === true) { sails.log.verbose(`${this.logHeader} createNotebook() -> Sending success response`); sails.log.debug(JSON.stringify(createResponse)); this.ajaxOk(req, res, null, { status: true, nb: nb['nbid'], name: name, message: 'createNotebook' }); } else { sails.log.error(`${this.logHeader} createNotebook() -> Sending failure response`); this.ajaxFail(req, res, createResponse.message, createResponse); } } catch (err) { sails.log.error(`${this.logHeader} createNotebook() -> Error thrown while sending response: `); sails.log.error(err); } } } Controllers.LabarchivesController = LabarchivesController; })(Controllers || (exports.Controllers = Controllers = {})); module.exports = new Controllers.LabarchivesController().exports(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTGFiYXJjaGl2ZXNDb250cm9sbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHlwZXNjcmlwdC9hcGkvY29udHJvbGxlcnMvTGFiYXJjaGl2ZXNDb250cm9sbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUtBLGlDQUErQjtBQUcvQjs7R0FFRztBQUNILDBFQUErRTtBQUMvRSxzQ0FBaUM7QUFDakMsMENBQXFDO0FBRXJDLElBQWMsV0FBVyxDQStXeEI7QUEvV0QsV0FBYyxXQUFXO0lBRXZCOzs7T0FHRztJQUNILE1BQWEscUJBQXNCLFNBQVEsK0JBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVTtRQUUxRCxnQkFBZ0IsR0FBUTtZQUNoQyxNQUFNO1lBQ04sVUFBVTtZQUNWLE9BQU87WUFDUCxNQUFNO1lBQ04sV0FBVztZQUNYLE1BQU07WUFDTixnQkFBZ0I7U0FDakIsQ0FBQztRQUdRLE1BQU0sR0FBUSxJQUFJLGVBQU0sRUFBRSxDQUFDO1FBQzNCLFNBQVMsR0FBVyx5QkFBeUIsQ0FBQztRQUVqRCxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUc7WUFDbEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNsQixJQUFJLENBQUMsTUFBTSxDQUFDLG9CQUFvQixHQUFHLGVBQWUsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDcEUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQztRQUM5RSxDQUFDO1FBRUQsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsR0FBRztZQUNyQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ2xCLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFB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