diff --git a/v2.0/handlers/apps_handlers.js b/v2.0/handlers/apps_handlers.js index 60a62b0f..36da4272 100755 --- a/v2.0/handlers/apps_handlers.js +++ b/v2.0/handlers/apps_handlers.js @@ -9,6 +9,7 @@ module.exports = { authorpis: authorpis, taphonomysystems: taphonomysystems, depositionalenvironments: depositionalenvironments, + meHandler: meHandler, validateusers: function(req, res, next) { const valuser = require('../helpers/validation/validateuser.js'); valuser.checktoken(req, res, next); @@ -290,4 +291,45 @@ function depositionalenvironments(req, res, next) { }); } +async function meHandler(req, res) { + const { orcid, sessionuuid } = req.user; + const db = req.app.locals.db; + + try { + // Look up the latest cached user info from ap.orcidlogins, + // and try to find a linked Neotoma contact (if any). + const sql = ` + SELECT + l.orcidid, + c.contactid, + COALESCE(c.contactname, l.orcidname) AS contactname + FROM ap.orcidlogins l + LEFT JOIN ndb.externalcontacts ec + ON ec.identifier = l.orcidid AND ec.extdatabaseid = 7 + LEFT JOIN ndb.contacts c + ON ec.contactid = c.contactid + WHERE l.sessionuuid = $1 + LIMIT 1 + `; + const rows = await db.any(sql, [sessionuuid]); + + if (rows.length === 0) { + // shouldn't happen — requireAuth already validated + return res.status(401).json({ status: 'unauthorized' }); + } + + return res.json({ + status: 'success', + data: { + orcid: rows[0].orcidid, + name: rows[0].contactname, + contactid: rows[0].contactid, // null if no link + sessionuuid, + }, + }); + } catch (err) { + console.error('meHandler failed:', err); + return res.status(500).json({ status: 'error', message: 'Failed to load user' }); + } +} diff --git a/v2.0/helpers/validation/newlogin.sql b/v2.0/helpers/validation/newlogin.sql index 845f2952..a0b89fb2 100644 --- a/v2.0/helpers/validation/newlogin.sql +++ b/v2.0/helpers/validation/newlogin.sql @@ -1,3 +1,3 @@ -INSERT INTO ap.orcidlogins (orcidid, userip, sessionuuid, expiresat) -VALUES (${orcidid}, ${ipaddr}, gen_random_uuid(), now() + interval '5 days') +INSERT INTO ap.orcidlogins (orcidid, userip, sessionuuid, expiresat, orcidname) +VALUES (${orcidid}, ${ipaddr}, gen_random_uuid(), now() + interval '5 days', ${orcidname}) RETURNING sessionuuid; \ No newline at end of file diff --git a/v2.0/helpers/validation/validateuser.js b/v2.0/helpers/validation/validateuser.js index 9e23b47f..8516961e 100644 --- a/v2.0/helpers/validation/validateuser.js +++ b/v2.0/helpers/validation/validateuser.js @@ -47,7 +47,10 @@ const checktoken = async function(req, res, next) { }); } else { const dbpush = await db.one(insertuserlogin, - {'orcidid': result['id'], 'ipaddr': ipaddr}); + {'orcidid': result['id'], 'ipaddr': ipaddr, + 'orcidname': result['name'] || + [result['given_name'], result['family_name']].filter(Boolean).join(' ') || + null}); const uuidres = await dbpush; res.status(200) .json({ diff --git a/v2.0/routes/apps.js b/v2.0/routes/apps.js index f281c8fa..6b4e8649 100755 --- a/v2.0/routes/apps.js +++ b/v2.0/routes/apps.js @@ -10,7 +10,7 @@ Last Updated: Aug 19, 2021 const express = require('express'); const router = express.Router(); const handlers = require('../handlers/apps_handlers'); -const {requireAuth} = require('../helpers/validation/sessionauth'); // requireAuth middleware +const {requireAuth} = require('../helpers/validation/sessionauth'); router.get('/', function(req, res, next) { res.send('NeotomaDB apps API: please provide a valid request'); @@ -66,6 +66,8 @@ router.get('/constdb', handlers.databasesummaries); router.get('/contactsummary/:datasetid', handlers.contactoverview); // Gives the orcid by the contactid. router.get('/orcids/contact', handlers.contact_orcid); +// Gives the logged in user their orcid and contactid. +router.get('/orcids/me', requireAuth, handlers.meHandler); // Gives the contact with an orcid. router.get('/orcids/orcid', handlers.orcid_contact); router.get('/datasetpi', handlers.datasetsbypi);