sotlas-api/users.js

212 wiersze
6.7 KiB
JavaScript

const express = require("express");
const {body, validationResult} = require('express-validator');
const config = require('./config')
const { expressjwt: jwt } = require('express-jwt')
const { expressJwtSecret } = require('jwks-rsa')
const db = require("./db");
const summitUtils = require('./summits');
let router = express.Router();
module.exports = router;
let jwtCallback = jwt({
secret: expressJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: config.sso.jwksUri
}),
algorithms: ['RS256']
});
const DB_COLLECTION_USERS = "users";
router.get("/me", jwtCallback, (req, res) => {
const reqUserId = req.auth.userid;
if (!reqUserId) {
return res.status(401).send("Missing userid in SSO token").end();
}
db.getDb().collection(DB_COLLECTION_USERS).findOne({userid: reqUserId}, (err, user) => {
if (err) {
return res.status(500).end();
}
if (!user) {
return res.status(404).end();
}
let summitObjectList = user.userSummits.map(userSummit => {
userSummit.summit = {code: userSummit.code};
delete userSummit.code;
return userSummit;
})
summitUtils.lookupSummits(summitObjectList)
.then(userDataWithSummits => {
user.userSummits = userDataWithSummits;
return res.json(user);
});
});
});
router.post("/me/settings",
jwtCallback,
(req, res) => {
const reqUserId = req.auth.userid;
if (!reqUserId) {
return res.status(401).send("Missing userid in SSO token").end();
}
const newSettings = Object.fromEntries(Object.entries(req.body).map(([k, v]) => ['settings.' + k, v]));
db.getDb().collection(DB_COLLECTION_USERS).updateOne(
{userid: reqUserId},
{$set: newSettings},
{upsert: true}
);
return res.status(200).end();
});
router.get("/me/tags", jwtCallback, (req, res) => {
const reqUserId = req.auth.userid;
if (!reqUserId) {
return res.status(401).send("Missing userid in SSO token").end();
}
db.getDb().collection(DB_COLLECTION_USERS).aggregate([
{ $match: {userid: reqUserId} },
{ $unwind: '$userSummits' },
{ $unwind: '$userSummits.tags' },
{ $match: { 'userSummits.tags': { $not: {$size: 0} }}},
{ $group: { _id: '$userSummits.tags', count: { $sum: 1 } } }
]).toArray().then(tagList => {
if(!tagList || tagList.length === 0) {
return res.json([]);
}
return res.json(tagList.map(tagItem => {
return {tag: tagItem._id, count: tagItem.count}
}));
}).catch(() => {
return res.status(500).end();
})
});
router.get("/me/summits/tags", jwtCallback, (req, res) => {
const reqUserId = req.auth.userid;
if (!reqUserId) {
return res.status(401).send("Missing userid in SSO token").end();
}
let queryParam = req.query.q ? req.query.q : []
if(!Array.isArray(queryParam)) {
queryParam = [queryParam];
}
db.getDb().collection(DB_COLLECTION_USERS).aggregate([
{ $match: {userid: reqUserId} },
{ $unwind: '$userSummits' },
{ $match: { 'userSummits.tags': { $in: queryParam } }},
{ $group: { _id: '$userid', codes: { $push: '$userSummits.code' } } }
]).toArray().then(summitCodeList => {
if (!summitCodeList || summitCodeList.length !== 1 ||
!summitCodeList[0].codes || summitCodeList[0].codes.length === 0) {
return res.json([]);
}
let summitObjectList = summitCodeList[0].codes.map(code => {
return {summit: {code: code}};
});
summitUtils.lookupSummits(summitObjectList)
.then(lookedUpSummits => {
return res.json(lookedUpSummits.map(lookedUpSummit => {return lookedUpSummit.summit}));
})
}).catch(err => {
return res.status(500).end();
})
});
router.get("/me/summit/:association/:code", jwtCallback, (req, res) => {
const reqUserId = req.auth.userid;
if (!reqUserId) {
return res.status(401).send("Missing userid in SSO token").end();
}
const code = req.params.association + "/" + req.params.code
db.getDb().collection(DB_COLLECTION_USERS).aggregate([
{ $match: {userid: reqUserId} },
{ $unwind: '$userSummits' },
{ $match: { 'userSummits.code': { $in: [code] } }},
{ $project: { _id: '$userid', userSummit: '$userSummits' } }
]).toArray().then(userSummits => {
if (!userSummits || userSummits.length === 0) {
return res.json({
summit: {code: code},
isBookmarked: false,
notes: "",
tags: []
})
}
if(userSummits.length !== 1) {
return res.status(500).end()
}
summitUtils.lookupSummits([{summit: {code: userSummits[0].userSummit.code}}])
.then(summitDetails => {
let requestedUserSummit = userSummits[0];
delete requestedUserSummit.userSummit.code;
requestedUserSummit.userSummit.summit = summitDetails[0].summit;
return res.json(requestedUserSummit.userSummit);
})
}).catch(err => {
return res.status(500).end();
});
});
router.post("/me/summit/:association/:code",
jwtCallback,
body("isBookmarked").isBoolean(),
body("notes").optional().trim().default(""),
body("tags").isArray(),
body("tags.*").isString(),
(req, res) => {
const reqUserId = req.auth.userid;
if (!reqUserId) {
return res.status(401).send("Missing userid in SSO token").end();
}
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({errors: errors.array()});
}
const code = req.params.association + "/" + req.params.code
const newSummitData = {
code,
isBookmarked: req.body.isBookmarked,
notes: req.body.notes,
tags: req.body.tags
};
db.getDb().collection(DB_COLLECTION_USERS).updateOne(
{userid: reqUserId},
{$pull: {userSummits: {code}}}
);
if (newSummitData.isBookmarked === true || newSummitData.notes !== "" || newSummitData.tags.length > 0) {
db.getDb().collection(DB_COLLECTION_USERS).updateOne(
{userid: reqUserId},
{$push: {userSummits: newSummitData}},
{upsert: true}
);
return res.status(201).end();
} else {
return res.status(204).end();
}
});