From 90f8fe7e538bb7e52d2558152a0390e693f39b11 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Thu, 29 Mar 2018 01:20:40 +0900 Subject: Introduce processor --- src/api/endpoints/users/show.ts | 209 ---------------------------------------- 1 file changed, 209 deletions(-) delete mode 100644 src/api/endpoints/users/show.ts (limited to 'src/api/endpoints/users/show.ts') diff --git a/src/api/endpoints/users/show.ts b/src/api/endpoints/users/show.ts deleted file mode 100644 index 78df23f339..0000000000 --- a/src/api/endpoints/users/show.ts +++ /dev/null @@ -1,209 +0,0 @@ -/** - * Module dependencies - */ -import $ from 'cafy'; -import { JSDOM } from 'jsdom'; -import { toUnicode, toASCII } from 'punycode'; -import uploadFromUrl from '../../common/drive/upload_from_url'; -import User, { pack, validateUsername, isValidName, isValidDescription } from '../../models/user'; -const request = require('request-promise-native'); -const WebFinger = require('webfinger.js'); - -const webFinger = new WebFinger({}); - -async function getCollectionCount(url) { - if (!url) { - return null; - } - - try { - const collection = await request({ url, json: true }); - return collection ? collection.totalItems : null; - } catch (exception) { - return null; - } -} - -function findUser(q) { - return User.findOne(q, { - fields: { - data: false - } - }); -} - -function webFingerAndVerify(query, verifier) { - return new Promise((res, rej) => webFinger.lookup(query, (error, result) => { - if (error) { - return rej(error); - } - - if (result.object.subject.toLowerCase().replace(/^acct:/, '') !== verifier) { - return rej('WebFinger verfification failed'); - } - - res(result.object); - })); -} - -/** - * Show a user - * - * @param {any} params - * @param {any} me - * @return {Promise} - */ -module.exports = (params, me) => new Promise(async (res, rej) => { - let user; - - // Get 'user_id' parameter - const [userId, userIdErr] = $(params.user_id).optional.id().$; - if (userIdErr) return rej('invalid user_id param'); - - // Get 'username' parameter - const [username, usernameErr] = $(params.username).optional.string().$; - if (usernameErr) return rej('invalid username param'); - - // Get 'host' parameter - const [host, hostErr] = $(params.host).optional.string().$; - if (hostErr) return rej('invalid username param'); - - if (userId === undefined && typeof username !== 'string') { - return rej('user_id or pair of username and host is required'); - } - - // Lookup user - if (typeof host === 'string') { - const username_lower = username.toLowerCase(); - const host_lower_ascii = toASCII(host).toLowerCase(); - const host_lower = toUnicode(host_lower_ascii); - - user = await findUser({ username_lower, host_lower }); - - if (user === null) { - const acct_lower = `${username_lower}@${host_lower_ascii}`; - let activityStreams; - let finger; - let followers_count; - let following_count; - let likes_count; - let posts_count; - - if (!validateUsername(username)) { - return rej('username validation failed'); - } - - try { - finger = await webFingerAndVerify(acct_lower, acct_lower); - } catch (exception) { - return rej('WebFinger lookup failed'); - } - - const self = finger.links.find(link => link.rel && link.rel.toLowerCase() === 'self'); - if (!self) { - return rej('WebFinger has no reference to self representation'); - } - - try { - activityStreams = await request({ - url: self.href, - headers: { - Accept: 'application/activity+json, application/ld+json' - }, - json: true - }); - } catch (exception) { - return rej('failed to retrieve ActivityStreams representation'); - } - - if (!(activityStreams && - (Array.isArray(activityStreams['@context']) ? - activityStreams['@context'].includes('https://www.w3.org/ns/activitystreams') : - activityStreams['@context'] === 'https://www.w3.org/ns/activitystreams') && - activityStreams.type === 'Person' && - typeof activityStreams.preferredUsername === 'string' && - activityStreams.preferredUsername.toLowerCase() === username_lower && - isValidName(activityStreams.name) && - isValidDescription(activityStreams.summary) - )) { - return rej('failed ActivityStreams validation'); - } - - try { - [followers_count, following_count, likes_count, posts_count] = await Promise.all([ - getCollectionCount(activityStreams.followers), - getCollectionCount(activityStreams.following), - getCollectionCount(activityStreams.liked), - getCollectionCount(activityStreams.outbox), - webFingerAndVerify(activityStreams.id, acct_lower), - ]); - } catch (exception) { - return rej('failed to fetch assets'); - } - - const summaryDOM = JSDOM.fragment(activityStreams.summary); - - // Create user - user = await User.insert({ - avatar_id: null, - banner_id: null, - created_at: new Date(), - description: summaryDOM.textContent, - followers_count, - following_count, - name: activityStreams.name, - posts_count, - likes_count, - liked_count: 0, - drive_capacity: 1073741824, // 1GB - username: username, - username_lower, - host: toUnicode(finger.subject.replace(/^.*?@/, '')), - host_lower, - account: { - uri: activityStreams.id, - }, - }); - - const [icon, image] = await Promise.all([ - activityStreams.icon, - activityStreams.image, - ].map(async image => { - if (!image || image.type !== 'Image') { - return { _id: null }; - } - - try { - return await uploadFromUrl(image.url, user); - } catch (exception) { - return { _id: null }; - } - })); - - User.update({ _id: user._id }, { - $set: { - avatar_id: icon._id, - banner_id: image._id, - }, - }); - - user.avatar_id = icon._id; - user.banner_id = icon._id; - } - } else { - const q = userId !== undefined - ? { _id: userId } - : { username_lower: username.toLowerCase(), host: null }; - - user = await findUser(q); - - if (user === null) { - return rej('user not found'); - } - } - - // Send response - res(await pack(user, me, { - detail: true - })); -}); -- cgit v1.2.3-freya