Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x | module.exports = (crowi, app) => { 'use strict' const debug = require('debug')('crowi:routes:share') const Share = crowi.model('Share') const ShareAccess = crowi.model('ShareAccess') const Tracking = crowi.model('Tracking') const ApiResponse = require('../util/apiResponse') const actions = {} async function firstOrCreateTrackingId(req) { const { trackingId } = req.session debug('ShereAccess from session', trackingId) if (!trackingId) { const userAgent = req.headers['user-agent'] const remoteAddress = req.headers['x-forwarded-for'] || req.connection.remoteAddress const tracking = await Tracking.create({ userAgent, remoteAddress }) debug('ShereAccess new created', tracking._id) return tracking._id } return trackingId } async function addAccessLog(req, share) { const trackingId = await firstOrCreateTrackingId(req) try { ShareAccess.access(share._id, trackingId) } catch (err) { console.error(err) } return trackingId } function hasAccessAuthority(secretKeywords, { uuid, secretKeyword }) { return !secretKeyword || secretKeywords[uuid] === secretKeyword } function updateShareIds(shareIds, id) { const unique = (id, index, array) => array.indexOf(id) === index return shareIds .concat(id) .filter(Boolean) .filter(unique) } function isExternalShareEnabled() { const config = crowi.getConfig() return Boolean(config.crowi['app:externalShare']) } actions.pageShow = async (req, res) => { const { uuid } = req.params const { shareIds = [], secretKeywords = {} } = req.session if (!isExternalShareEnabled()) { res.status(405) return res.render('405') } try { const share = await Share.findShareByUuid(uuid, { status: Share.STATUS_ACTIVE }) const shareId = share.uuid const trackingId = await addAccessLog(req, share) req.session.trackingId = trackingId if (hasAccessAuthority(secretKeywords, share)) { req.session.shareIds = updateShareIds(shareIds, uuid) const page = share.page const { path = '', revision = {} } = page return res.render('page_share', { hasSecretKeyword: true, shareId, page, path, revision }) } return res.render('page_share', { hasSecretKeyword: false, shareId }) } catch (err) { console.error(err) return res.redirect('/') } } const api = (actions.api = {}) api.list = async (req, res) => { // list is allowed if the feature is disabled because it is used in admin page let { page_id: pageId, page = 1, limit = 50, populate_accesses: populateAccesses = false } = req.query page = parseInt(page) limit = parseInt(limit) const query = pageId ? { page: pageId } : {} const options = { page, limit, populateAccesses } try { const shareData = await Share.findShares(query, options) const result = { share: shareData } return res.json(ApiResponse.success(result)) } catch (err) { return res.json(ApiResponse.error(err)) } } api.get = async (req, res) => { const { page_id: pageId, populate_accesses: populateAccesses = false } = req.query if (pageId === null) { return res.json(ApiResponse.error('Parameters page_id is required.')) } try { const shareData = await Share.findShareByPageId(pageId, { status: Share.STATUS_ACTIVE }, { populateAccesses }) const result = { share: shareData } return res.json(ApiResponse.success(result)) } catch (err) { return res.json(ApiResponse.error(err)) } } /** * @api {post} /shares.create Create new share * @apiName CreateShare * @apiGroup Share * * @apiParam {String} id * @apiParam {String} page_id */ api.create = async (req, res) => { if (!isExternalShareEnabled()) { return res.status(405) } const { page_id: pageId = null } = req.body if (pageId === null) { return res.json(ApiResponse.error('Parameters id and page_id are required.')) } try { const shareData = await Share.create(pageId, req.user) if (!shareData) { throw new Error('Failed to create share.') } const result = { share: shareData.toObject() } return res.json(ApiResponse.success(result)) } catch (err) { return res.json(ApiResponse.error(err)) } } /** * @api {post} /shares.delete Delete share * @apiName DeleteShare * @apiGroup Share * * @apiParam {String} page_id Page Id. */ api.delete = async (req, res) => { if (!isExternalShareEnabled()) { return res.status(405) } const { page_id: pageId } = req.body try { const shareData = await Share.findShareByPageId(pageId, { status: Share.STATUS_ACTIVE }) await Share.deleteById(shareData.id) debug('Share deleted', shareData.id) const result = { share: shareData.toObject() } return res.json(ApiResponse.success(result)) } catch (err) { debug('Error occured while get setting', err, err.stack) return res.json(ApiResponse.error('Failed to delete share.')) } } api.setSecretKeyword = async (req, res) => { if (!isExternalShareEnabled()) { return res.status(405) } const { share_id: shareId, secret_keyword: secretKeyword } = req.body try { const share = await Share.findShareByUuid(shareId) share.secretKeyword = secretKeyword const shareData = await share.save() const result = { share: shareData.toObject() } return res.json(ApiResponse.success(result)) } catch (err) { debug('Error occured while update secret keyword', err, err.stack) return res.json(ApiResponse.error('Failed to update secret keyword.')) } } api.checkSecretKeyword = async (req, res) => { if (!isExternalShareEnabled()) { return res.status(405) } const { share_id: shareId, secret_keyword: secretKeyword } = req.body const { shareIds = [], secretKeywords = {} } = req.session req.session.secretKeywords = Object.assign(secretKeywords, { [shareId]: secretKeyword }) try { const share = await Share.findShareByUuid(shareId, { status: Share.STATUS_ACTIVE }) const result = { hasAccessAuthority: hasAccessAuthority(req.session.secretKeywords, share) } if (result.hasAccessAuthority) { req.session.shareIds = updateShareIds(shareIds, shareId) } return res.json(ApiResponse.success(result)) } catch (err) { return res.json(ApiResponse.error(err)) } } return actions } |